2012-04-08 20 views
2

私は誰かにこのコードスニペットを捨てて、私を混乱させるようにしたいと思います。非静的C++メンバ関数へのコールバック

//------------------------------------------------------------------------------- 
    // 3.5 Example B: Callback to member function using a global variable 
    // Task: The function 'DoItB' does something that implies a callback to 
    //  the member function 'Display'. Therefore the wrapper-function 
    //  'Wrapper_To_Call_Display is used. 

    #include <iostream.h> // due to: cout 

    void* pt2Object;  // global variable which points to an arbitrary object 

    class TClassB 
    { 
    public: 

     void Display(const char* text) { cout << text << endl; }; 
     static void Wrapper_To_Call_Display(char* text); 

     /* more of TClassB */ 
    }; 


    // static wrapper-function to be able to callback the member function Display() 
    void TClassB::Wrapper_To_Call_Display(char* string) 
    { 
     // explicitly cast global variable <pt2Object> to a pointer to TClassB 
     // warning: <pt2Object> MUST point to an appropriate object! 
     TClassB* mySelf = (TClassB*) pt2Object; 

     // call member 
     mySelf->Display(string); 
    } 


    // function does something that implies a callback 
    // note: of course this function can also be a member function 
    void DoItB(void (*pt2Function)(char* text)) 
    { 
     /* do something */ 

     pt2Function("hi, i'm calling back using a global ;-)"); // make callback 
    } 


    // execute example code 
    void Callback_Using_Global() 
    { 
     // 1. instantiate object of TClassB 
     TClassB objB; 


     // 2. assign global variable which is used in the static wrapper function 
     // important: never forget to do this!! 
     pt2Object = (void*) &objB; 


     // 3. call 'DoItB' for <objB> 
     DoItB(TClassB::Wrapper_To_Call_Display); 
    } 

質問1:この関数呼び出しについて:その宣言に従ってchar*引数を取ることになっているが、任意の引数を取るWrapper_To_Call_Displayしないのはなぜ

DoItB(TClassB::Wrapper_To_Call_Display) 

質問2:DoItBは、私がこれまで理解してきたことさえ厳しいDoItBが引数として関数ポインタを取りますが、なぜ関数呼び出しDoItB(TClassB::Wrapper_To_Call_Display)引数としてTClassB::Wrapper_To_Call_Displayを取るということです

void DoItB(void (*pt2Function)(char* text)) 

として宣言されていますポインタではありませんか?

予めありがとうコードスニペットの

元:C/C++でhttp://www.newty.de/fpt/callback.html

答えて

3

関数名がパラメータなしで使用する場合 - すなわち、NO括弧ではない - それは関数へのポインタです。したがって、TClassB::Wrapper_To_Call_Displayは、関数のコードが実装されているメモリ内のアドレスへのポインタです。 TClassB::Wrapper_To_Call_Display以来

は、単一char*それは時間ですがかかるvoid関数へのポインタがvoid (*)(char* test)ですので、DoItBによって必要な型と一致します。

+0

ありがとう、非常に有益な回答 – exTrace101

関連する問題