1

我需要在某处存储这样的成员函数指针:

void Class1::function1(int a, int b)
{
  ...
}

struct parameters
{
   int a;
   int b;
}

myStoreClass.store(&Class1::function1, parameters);

然后可以像这样稍后调用它:

myStoreClass.call();

以便使用适当的参数调用该函数。

由于它是一个成员函数,我想我也应该存储一个 Class1 对象指针,但是我怎样才能存储一个带有模板的成员函数指针呢?

4

2 回答 2

0

您需要参数化成员函数所在的对象类型,并将指针传递给该函数。为了调用成员函数,您还需要传递一个指向对象的指针,以及调用的参数。这是一个示例:

class Foo 
{
public:
    void DoIt (int a, int b)
    {   
    }   
};

class Bar 
{
public:
    void DoItAgain (int x, int y)
    {   
    }   
};

template <typename Obj>
void DoSomething (Obj* that, void (Obj::*fnThat)(int,int), int i, int j)
{
    (that->*fnThat)(i, j); 
}

int main()
{
    Foo foo;
    Bar bar;

    void (Foo::*fnFoo)(int,int) = &Foo::DoIt;

    (foo.*fnFoo)(42,43);

    DoSomething (&foo, fnFoo, 99, 100);
    DoSomething (&bar, &Bar::DoItAgain, 200, 300);
}
于 2013-07-31T16:11:17.617 回答
0

如果您使用的是 C++11 编译器,那么它相当简单。给定这个类:

class Class1 {
public:
    void function1(int a, int b);
};

您可以使用std::bind准备一个呼叫:

#include <functional>
// ...

Class1 class1Obj;
auto myStore = std::bind(&Class1::function1, &class1Obj, 10, 20);

你可以稍后调用它:

myStore();
// The above has the same effect as:
// class1Obj.function1(10, 20);

您实际上根本不需要 StoreClass (这几乎已经是什么std::bind了。)

这只是一个例子。您显然需要确保在class1Obj执行调用时(在上面的示例中)调用 Class1::function1() 的 Class1 实例仍然存在。

如果您不在 C++11 上,则可以改用Boost

#include <boost/function.hpp>
#include <boost/bind.hpp>
// ...

boost::function<void()> myStore = boost::bind(&Class1::function1,
                                              &class1Obj, 10, 20);

电话是一样的:

myStore();

在这两种情况下,返回的函数类型bind都是void (). 意味着一个函数返回void并且不接受任何参数(因为它们已经被绑定“吞噬”了。)所以如果你仍然需要创建一个模板来参数化你可以存储的成员函数调用的类型,你只需要做等等成员函数的返回类型,而不是它们的参数。例如:

template <typename T>
// ...
std::function<T ()> storedCall;
// or with Boost:
// boost::function<T ()> storedCall;

请注意,Boost.Bind 和 Boost.Function 是仅头文件库。这意味着它们易于使用,并且根本不需要您链接任何库。

于 2013-07-31T16:15:49.877 回答