2012-03-12 26 views
1

この質問は、私がしようとしているものに似ていますCalling C++ member function pointer from a struct。 しかし、私の構造体には、別のクラスで定義されているメンバ関数ポインタが含まれています。構造体が定義されて使用されています。次に、クラス、構造体、関数ポインタのレイアウト例を示します。あなたが見ることができるようにC++で構造体配列のメンバであるメンバ関数ポインタを呼び出す構文は何ですか?

// Alpha.h: 
class Alpha{ 
public: 
    void function1(char name[], int number); 
    void function2(char name[], int number); 
    void function3(char name[], int number); 

    typedef void (Alpha::*My_func_ptr)(char name[], int number); 

    static My_func_ptr functionTable[]; 
}; 

// Alpha.cpp: 
#include "Alpha.h" 

Alpha::My_func_ptr Alpha::functionTable[] = { 
    &Alpha::function1, 
    &Alpha::function2, 
    &Alpha::function3 
}; 

void Alpha::function1(char name[], int number) 
{ 
    //some stuff 
} 

void Alpha::function2(char name[], int number) 
{ 
    //some stuff 
} 

void Alpha::function3(char name[], int number) 
{ 
    //some stuff 
} 

// Beta.h: 
#include "Alpha.h" 

typdef struct{ 
    char bName[10]; 
    Alpha::My_func_ptr fptr; 
}ptr_structure; 

class Beta{ 
public: 
     void betafunction(); 

     Alpha alphaobject; 
     ptr_structure str_array[3]; 
}; 

// Beta.cpp: 
#include "Beta.h" 

void betafunction() 
{ 
    str_array[0].fptr = alphaobject.functionTable[0]; 
    str_array[1].fptr = alphaobject.functionTable[1]; 
    str_array[2].fptr = alphaobject.functionTable[2]; 

    (str_array[0].fptr)("name", 1); //gives error expression must have 
            //(pointer-to-) function type 

    (this->*str_array[0].fptr)("name", 1); 
    //error pointer-to-member selection class types are incompatible "Beta" and "Alpha" 

    //sample function pointer call using function table from other class, 
    //this syntax compiles and runs without error. 
    (alphaobject.*Alpha::functionTable[0]("name", 1); 
} 

私がarrayから関数ポインタを呼び出すことができますが、構造体の配列内から関数ポインタを呼び出す方法を見つけ出すように見えることはできません。

+6

'function pointer'と' member function pointer'を区別してみてください。それらは非常に異なっています。 –

+0

また、あなたのコードは(typo 'typdef'のために)コンパイルされません。実際にコードをコピーしてください。 –

+0

ありがとうJesse、私はタイトルを編集するか、質問テキストに追加するだけですか? – ryan

答えて

3

メンバ関数を通じてポインタを呼び出すとき、あなたはそのポインタに関連付けられたオブジェクトのインスタンスを持っている必要があります:

(alphaobject.*(str_array[0].fptr))("name", 1) 
    ^^^^^^^^^^^ 
+0

マイケルさん、ありがとうございました。これが答えでした。 Alphaの中で宣言された関数ポインタを呼び出すので、そのポインタにアクセスするためにそのクラスのオブジェクトが必要であると推測しています。あなたの答えをより良く理解できるように、示唆された読書がありますか? – ryan

+1

@ryan:http://www.parashift.com/c++-faq-lite/pointers-to-members.htmlを参照してください。 –

0

私が思うだろう:

(object.*functionTable[0])(args, ...); 
(objptr->*functionTable[0])(args, ....); 

IIRC、objectの組み合わせと.*オペレータが大きな単項演算子のようなものです。だから、[0]の優先順位が低いです。しかし、それはまた、関数呼び出し後置演算子より低いprededenceを持って(args, ...)

類推:通常の関数を呼び出すときに*オペレータが必要とされていないもちろん

(*foo)(); /* classic C */ 

。しかし、もしあなたがそれを書いたら、*foo()は何かを意味するので、あなたは括弧が必要です。

+0

入力していただきありがとうございますが、オブジェクト* Alpha :: functionTable [0]コールは構文の動作例です。私は関数ポインタ呼び出し(str_array [0] .fptr)(args)を取得しようとしています。 – ryan

+0

この回答は次のとおりです。あなたは 'functionTable [0]'を取り出して別の場所に保存しました。だから、 'functionTable [0]'という表現を「どこか他のどこか」にアクセスする表現に置き換えてください。それでもオブジェクトは必要です。そのクラスをメンバとするオブジェクトなしでメンバへのポインタを呼び出すことはできません。私。 (オブジェクト。*(EXPR))(args、...);ここで、EXPRは、それがどこにあっても、メンバーへのポインタを参照します。そして、メンバへのポインタのクラスはもちろん、オブジェクトのクラスに一致しなければなりません! – Kaz

+0

また、なぜメンバー以外の関数で 'this'を使用していますか?あなたはそれを評価するために何を期待していますか、そのタイプは何ですか? – Kaz

0

あなたはコードをする方法を読めるに応じて、2つのソリューションのいずれかに行くことができます。読めないバージョン(でも、間違っているかもしれない、と私もコンパイルしようとしません):

void Beta::betafunction() { 
    Alpha a; 
    (a.*(strArray[0].fptr))("name",1); 
} 

しかし、私は実際に物事が少しシンプルにしようとします:

void Beta::betafunction() { 
    Alpha a; 
    Alpha::My_func_ptr mptr = strArray[0].fptr; 
    (a.*mptr)("name",1); 
} 

私は信じていますコンパイラはmptrを非常に簡単に最適化できるので、の専門家とシンタックスを再生しようとしても意味がありません。

関連する問題