我正在尝试用C ++实现一个观察者模式(各种各样)并且我想使用函数指针这样做,但是当我尝试将一个函数指针从类B转换为一个typedef函数指针时,我一直收到错误:
#include <map>
typedef int (*OutputEvent)(const char*, const char*, int);
class A
{
private:
int nextListenerId;
std::map<int, OutputEvent> listenerMap;
public:
A(){ nextListenerId = 0;}
~A(){}
inline int RegisterListener(OutputEvent callback)
{
nextListenerId++;
listenerMap[nextListenerId] = callback;
return nextListenerId;
}
};
class B
{
private:
int listenerId;
public:
B(const A& a)
{
OutputEvent e = &B::CallMeBack;
listenerId = a.RegisterListener(e);
}
~B(){}
int CallMeBack(const char* x, const char* y, int z)
{
return 0;
}
};
我创建了这个示例并且我pasted it into codepad.org,但是当我无法编译时(它不能在codepad.org或Visual Studio 2010中编译):
Output:
t.cpp: In constructor 'B::B(const A&)':
Line 28: error: cannot convert 'int (B::*)(const char*, const char*, int)' to 'int (*)(const char*, const char*, int)' in initialization
compilation terminated due to -Wfatal-errors.
我不明白为什么它无法转换函数指针。请问有人帮帮我吗?
答案 0 :(得分:1)
您尝试转换为OutputEvent
的功能是成员函数。这在错误消息中清楚地表示出来:
'int (B::*)(const char*, const char*, int)'
与
不同 int (*OutputEvent)(const char*, const char*, int)
因为B::
部分(这意味着该函数具有不可见的this
参数)。
如果您将成员函数定义为静态,那么您将能够将其转换为OutputEvent
:
class B
{
....
static int CallMeBack(const char* x, const char* y, int z);
...
};
答案 1 :(得分:0)
成员函数与typedef'd原型不匹配,因为成员函数具有不可见的'this'参数。使它成为一个静态函数,它应该工作。
答案 2 :(得分:0)
类成员函数有一个隐藏参数,即全局函数没有的对象。
做这样的事情: -
B*pB;
int CallMeBack(const char* x, const char* y, int z)
{
return pB->CallMeBack(x,y,z);
}
如果您在旅途中同时进行多次回调,则会更加困难。但如果只有一个,你可以指向对象并通过它调用。