我想存储一个指向对象的指针和指向它的已知签名方法的指针。如果我知道该类,那么这个指针有类型:
int (MyClass::*pt2Member)(float, char, char)
但是,如果我不知道类型,我怎么能存储指针?
我想做这样的事情:
myObject.callThisFuncLater(&otherObject, &otherObject::method)
如何在method
中存储方法myObject
的指针并稍后再调用?
答案 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 ++中使用成员函数指针很有帮助,请重新考虑您的设计。