2011-07-27 16 views
2

C++でオブザーバパターン(ソート)を実装しようとしていますが、関数ポインタを使用してキャストしようとするとエラーが発生します。 typedefの関数ポインタへのクラス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):

私はfunctioを変換できない理由がわかりませんn個のポインタ。誰も私を助けてくれますか?

+1

これは前に何度も尋ねられています:http://stackoverflow.com/questions/4210710/cast-pointer-to-member-function-to-normal-pointer and more。 http://www.parashift.com/c++-faq-lite/pointers-to-members.htmlも参照してください。 –

+0

http://stackoverflow.com/questions/1151582/pthread-function-from-a-classも参照してください。 –

答えて

1

OutputEventにキャストしようとしている関数は、のです。これは、これによりエラーメッセージに明確に表される:

'int (B::*)(const char*, const char*, int)' 

ため(すなわち、機能を不可視thisパラメーターを有することを意味する)B::一部の

int (*OutputEvent)(const char*, const char*, int) 

とは異なるタイプです。

あなたはstaticとしてあなたのメンバ関数を定義する場合は、あなたがOutputEventにキャストすることができるようになります:

class B 
{ 
    .... 
    static int CallMeBack(const char* x, const char* y, int z); 
    ... 
}; 
+0

OK、私はこれに対する私の解決策は実際にオブザーバパターンを実装し、2種類のオブザーバを持つことだと考えています: 'B'は' Observer'インタフェースを実装し、他の誰かがOutputEvent関数ポインタを使いたい場合は、コンストラクタ内のOutputEvent関数ポインタを受け取る 'C'クラスを使用します(' C'は 'Observer'インタフェースも実装します)。このようにして、メンバー関数、静的関数、またはグローバル(???)関数にコールバックすることができます。 – Kiril

0

メンバ関数が見えない 'this'パラメータを持つため、メンバ関数はtypedefのプロトタイプと一致しません。それを静的関数にするとうまくいくはずです。

0

クラスのメンバ関数は、グローバル関数がないオブジェクトを、隠しパラメータを持っています持ってる。

このような何か: - あなたは、同時に、外出先で複数のコールバックを持っている場合

B*pB; 

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

より困難に。しかし、1つしかない場合は、オブジェクトへのポインタを持ち、これを介して呼び出すことができます。

関連する問題