2010-12-08 40 views
3

私はC++で関数ポインタを理解しようとしていますので、私のプロジェクトでこれらをうまく使うことができます。私は論理的な問題に遭遇している。親クラスと親クラスを継承する子クラスの2つのクラスがあるとします。親クラスのメンバ関数への関数ポインタ

class Parent{ 
    ...other stuff 
    void (Parent::*ptr2func)(); 
    ...other stuff 
}; 

その後、我々は、子クラスがあります。

class Child : public Parent{ 
     ...other stuff 
     void afunc(); 
     ...other stuff 
}; 

私は子クラスのafunc()関数に親クラスのポインタを接続したかったです。私はそうのようにそれを行うことを試みたところ、子クラスのコンストラクタである:

Child::Child() 
    { 
    ptr2func = &Child::afunc; 
    } 

は、これが予想されるエラーを返しました: が割り当てにvoid (Parent::*)()void (Child::*)()を変換することはできません。

私はそのようなことが起こるのを恐れていました。しかし、どうすればこれを乗り越えることができますか?親クラスのメンバ関数への関数ポインタを子クラスのメンバ関数にリンクできませんか?あなたが理解できるように、私は仮想関数を使用せずに、実験のためだけに関数ポインタを使って多態性を達成しようとしています。私はこれが可能であると信じるように導いた。私の間違いは何ですか?それとも不可能なのでしょうか?

+3

あなたは**本当に**何をしようとしていますか?すでに継承スキームが設定されています。関数ポインタと一緒に何かをハックしようとするのではなく、 'virtual'関数を使って多形的な振舞いを得るのはなぜですか? –

+2

[C++の継承とメンバ関数のポインタ]の複製が可能です。(http://stackoverflow.com/questions/60000/c-inheritance-and-member-function-pointers) –

+0

私はKarl Knechtelが言ったことに同意します。 'virtual'キーワードはすでにコンパイラにあなたのためのすべての苦労をしています。 – Mephane

答えて

5

void (Parent::*)()は、タイプがParentのオブジェクトを受け取ります。関数Child::afuncには、子タイプのオブジェクトが必要です。したがって、ポインタをvoid (Parent::*)()に変換すると、無効な呼び出しが可能になります。

メンバ関数ポインタは、実際に多態性を実装するために使用することはできません。仮想使用せずに多型を実装する従来の方法は、通常の関数ポインタを使用することです:

struct MyBaseClass 
{ 
    void (*function)(MyBaseClass* this_pointer); 
}; 
+0

'Child :: afunc'が親の仮想関数のオーバーライドだったらうまくいくでしょうか? – sje397

+0

ああ、クラスのオブジェクトにポインタを渡すことで、多態性を達成したいすべての関数の引数としてこれを実装できますか? – Lefteris

2

その変換はあなたがへのポインタまたは参照して、クラスの子で関数を呼び出すことができるだろうとして働いていた場合、それは危険です子ではないかもしれない親。

関数とポインタ/参照を渡す場合は、boost :: bindを使用してそれを達成することができます。

+0

+1のboost :: bind ;-) –

関連する問題