如何使用typedef函数指针来注册回调

时间:2011-07-27 15:33:35

标签: c++ compiler-errors function-pointers observer-pattern

我正在尝试用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.

我不明白为什么它无法转换函数指针。请问有人帮帮我吗?

3 个答案:

答案 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);
}

如果您在旅途中同时进行多次回调,则会更加困难。但如果只有一个,你可以指向对象并通过它调用。