5

我想存储一个指向对象的指针和一个指向它的已知签名方法的指针。如果我知道该类,则此指针具有类型:

int (MyClass::*pt2Member)(float, char, char)

但是,如果我不知道类型,如何存储指针?

我想做这样的事情:

myObject.callThisFuncLater(&otherObject, &otherObject::method)

如何存储指向方法的指针methodmyObject稍后调用它?

4

4 回答 4

5

如果您可以访问 TR1 STL 库扩展(在 gcc 和 Visual Studio 2008 及更高版本上可用),最简单的方法是。std::function 和 std::bind 可用于包装可以稍后调用的调用。此功能在 boost 函数和 boost 绑定中也可用:

#include <functional>

class MyClass {
public:
  template<typename T> callThisFuncLater(T& otherObject,
                                         int(T::*)(float, char, char) method) {
    return storedInvocation_ = std::bind(otherObject, 
                                  method, 
                                  std::placeholders::_1,   // float
                                  std::placeholders::_2,   // char
                                  std::placeholders::_3);  // char
  }

  int callStoredInvocation(float a, char b, char c) {
    storedInvocation_(a, b, c);
  }

private:
  std::function<int(float, char, char)> storedInvocation_;
};
于 2011-10-16T19:47:59.027 回答
4

没有像最初内置在语言或标准库中那样简单的方法来执行此操作(尽管最近已添加)。如果您熟悉 Boost,它们包含一个解决方案 - Boost.Function

但是,如果由于某种原因,您不能或不愿意使用 Boost,则可以使用模板来执行此操作(诚然,这与 Boost 的解决方案非常相似):

class FncPtr
{
public:
    virtual int call(float, char, char) = 0;
};

template <typename T>
class ClassFncPtr : public FncPtr
{
     int (T::*pt2Member)(float, char, char);
     T *inst;
public:
     ClassFncPtr(T* who, int (T::*memfunc)(float,char,char))
         : inst(who), pt2Member(memfunc)
     {
     }
     int call(float a, char b, char c)
     {
         return (inst->*pt2Member)(a,b,c);
     }
};

template <typename T>
FncPtr * makeFuncPointer(T* who, int (T::*memfunc)(float,char,char))
{
    return new ClassFncPtr<T>(who,memfunc);
}

如果您愿意,您还可以子类FncPtr化以便能够使用非类函数。

于 2011-10-16T19:58:34.847 回答
2

您可以使用boost::function(and boost::bind) 来存储一段代码以供以后调用。

class MyClass
{
public:
    void callThisFuncLater( boost::function< int (float, char, char) > callBack );
};
...
myObject.callThisFuncLater( boost::bind( &otherObject::method, &otherObject ) );
于 2011-10-16T19:46:12.490 回答
0

我个人会选择不同的设计。仅仅是因为 C++ 中的成员函数指针不容易使用。就我个人而言,我会选择使用接口并从这些接口继承并沿着这些接口进行解析。

成员函数指针的问题之一是它们在不同编译器上的实现方式不同。如果您使用 Borland/Embarcardero 编译器并希望限制自己,您可以使用__closure关键字,但很可能您不是,因此您必须使用其他一些编译器特定的实现,或者使用 boost 助手之一类之类的函数。

但是,如果您发现在 C++ 中使用成员函数指针很有帮助,请重新考虑您的设计。

于 2011-10-16T19:51:29.597 回答