Как использовать указатель функции typedef для регистрации обратного вызова - PullRequest
2 голосов
/ 27 июля 2011

Я пытаюсь реализовать шаблон наблюдателя (своего рода) с 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;
    }
};

Я создал этот пример и вставил его в 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 ]

1 голос
/ 27 июля 2011

Функция, которую вы пытаетесь привести к 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);
   ...
 };
0 голосов
/ 27 июля 2011

Функция-член класса имеет скрытый параметр, объект, которого нет в глобальной функции.

Сделайте что-то вроде этого: -

B*pB;

int CallMeBack(const char* x, const char* y, int z)
{
    return pB->CallMeBack(x,y,z);
}

Сложнее, если у вас есть несколько обратных вызовов на ходу одновременно. Но если есть только один, вы можете иметь указатель на объект и вызывать через него.

0 голосов
/ 27 июля 2011

Функция-член не соответствует прототипу typedef, потому что функции-члены имеют невидимый параметр this.Сделайте это статической функцией, и она должна работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...