2011-12-22 12 views
3

への関数ポインタ、私は何が必要2クラスC++:他のクラスの機能

class B { 
public: 
    int func(int i); 
}; 

class A { 
public: 
    typedef int (B::*fPtr)(int); 
    void run(); 
    B* mB; 
}; 

void A::run() { 
    // create a pointer 
    fPtr p = &(B::func); 
    // invoke the function 
    mB->*p(2);  <------- Compilation Error 
} 

を持っているが、Aの実行機能に)(FUNCへのポインタを作成することです。 mBが1つの引数を持つ関数に対応していないというコンパイルエラーが発生します。なぜあなたはmB->func(2);を呼び出すことはできません

+0

なぜあなたは、これは非常に複雑作っているの?なぜそれを継承でタグ付けしましたか?それを使用していないときは?インターフェイスについて聞いたことがありますか? –

+1

std :: function/boost ::関数を使わないのはなぜですか?それらは、愚かなCスタイルの関数ポインタよりもはるかに柔軟で、ずっとシンプルです。 – Lalaland

+1

@EthanSteinbergメンバ関数のポインタはCの関数ポインタとほとんど関係がなく、 'std/boost :: function'には格納できません。 –

答えて

2

クラスのインスタンスメソッドは、thisポインタのために常に隠された最初のパラメータを持ちます。したがって、関数ポインタのtypedefと互換性がありません。メンバ関数へのポインタを直接取得する方法はありません。一般的な回避策は、メンバー関数を呼び出すことができる選択したポインタに静的にキャストできる一般的な "catch all"パラメータ(たとえばvoid *)を受け入れる静的関数を渡す "サンク"を使用することです。例:

class B 
{ 
public: 
    static void MyThunk(void * obj) 
    { 
     static_cast<B *>(obj)->MyRealFunc(); 
    } 

    void MyRealFunc() 
    { 
     // do something here 
    } 

    // . . . 
}; 

あなただけB::MyThunkを使用してそれを参照、それは「隠れたthis」を持っていないとして容易に静的関数へのポインタを取得することができます。関数に追加のパラメータが必要な場合は、functorのようなものを使用して、必要なパラメータと状態を取得できます。

あなたは間違いなく、すべてこのことについて、あなたがはるかに伝え、このC++よくある質問Liteのページ読んでください:Pointers to member functions

+0

良い答え。なぜ 'obj'の型は' void * 'なのですか?私は 'B *'が好きです。 –

+0

@bobbymcr:前に ' - > *'と '。*'演算子を使ったことがないと思いますか?彼らは、アレックスの例が示すように、ポインタを介してオブジェクトインスタンスのメソッドを呼び出すことができます。彼は自分のコードを正しくコンパイルするために括弧を欠いていた。 –

+1

@DavidGrayson:通常、Win32で 'CreateThread'のようなものと相互に作用するために、いくつかの"裸の骨 "のポインタ型を使用しなければなりません。これは' ThreadStart'関数ポインタに 'LPVOID'を渡すだけです。できるだけ強く型付けされたものを作成する必要がありますが、必ずしも選択肢がありません。 – bobbymcr

1

を助けてください?

あなたはおそらく、あなたは関数式の前後に括弧を挿入する必要がvirtual関数やクラスの継承

+0

)私のプロジェクト設計と私がこれを達成したい目標が与えられれば、私が行っている解決策です。 –

6

に見てBのためのさまざまな機能が必要な場合:

(mB->*p)(2); 

しかし、他の人が指摘したように、ほぼ確実にありますあなたがやろうとしていることをやるより良い方法です。

+0

まず、おかげさまで、ありがとうございます。上記の他のものを使用する場合は、私の場合はこの解決策が最も適していると思います。 –