c ++存储指向未知类的成员函数的指针

时间:2011-10-16 19:33:24

标签: c++ pointers callback function-pointers member-function-pointers

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

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

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

我想做这样的事情:

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

如何在method中存储方法myObject的指针并稍后再调用?

4 个答案:

答案 0 :(得分: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_;
};

答案 1 :(得分:3)

最初内置于语言或标准库中的方法没有简单的方式(尽管最近已添加)。如果您熟悉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子类化为能够使用非类函数。

答案 2 :(得分:2)

您可以使用boost::function(和boost::bind)来存储稍后要调用的代码。

class MyClass
{
public:
    void callThisFuncLater( boost::function< int (float, char, char) > callBack );
};
...
myObject.callThisFuncLater( boost::bind( &otherObject::method, &otherObject ) );

答案 3 :(得分:-1)

我个人会选择不同的设计。仅仅因为C ++中的成员函数指针不易使用。我个人会选择使用接口并从这些接口继承并解析这些接口。

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

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