2012-01-27 7 views
1

今度は、クラスの関数ポインタが別のクラスの関数を指していますか?このクラスの関数ポインタをこの他のクラスの関数で埋めることができない

class Apple 
{ 
    int(Apple::*pActionFunc)(void); 
}; 

class Tree 
{ 
    Apple* tempy; 

    void Init(void); 

    int I_Work(void); 
}; 

void Tree::Init(void) 
{ 
    tempy = new Apple(); 
    tempy->pActionFunc = &Tree::I_Work; 
} 

int Tree::I_Work(void) 
{ 
    "Do Things" 
} 

動作しません:それは私の質問

例です。何故ですか?

+1

なぜファンクタまたはインターフェイスを使用できるときに関数ポインタを使用しますか? – AlexTheo

+0

http://blogs.msdn.com/b/oldnewthing/archive/2004/02/09/70002.aspxこれはメソッドポインタについての非常に良い情報です。とにかく私はこの仕事をすることができますを楽しむと助けてください – Nico

答えて

5

すべての変数と同様に、関数ポインタも型を持ち、変数型のアドレスを格納するために同じ型へのポインタしか使用できないため、これは機能しません。

int(Apple::*pActionFunc)(void); 

pActionFuncパラメータとしてvoidを取り、intを返すAppleクラスのメンバ関数へのポインタであるコンパイラーに指示します。

tempy->pActionFunc = &Tree::I_Work; 

入力パラメータとしてvoidを取り、intを返すTreeクラスのメンバー関数I_Work()のアドレスを格納する試み。

これらが異なるクラスのメンバ関数であることに気がつくと、エラーが発生します。

+0

?私が必要とするのは、第2クラスの関数に接続する関数ポインタを保持できる最初のクラスだけです –

1
void foo(int); 
void (*pfunc)(double); 
pfunc = foo;   // This is an error 

なぜこのエラーが発生しますか? pfuncはfooとは異なるパラメータを取るためです。それはここで起こっているのと同じことです。 Tree::I_Workは、パラメータを取らずにintを返す関数なので、パラメータを取らずにintを返すAppleの関数と互換性があるはずです。しかし、そうではありません。次のようにI_Workを呼び出すことはできません:

x = I_Work(); 

できますか?いいえ、Treeオブジェクトが必要です。

a_tree.I_Work(); 

これは、メンバー関数が基本的に無料の関数とは異なることに気がつくはずです。メンバ関数には隠しパラメータがあります。実際には、それは本当に隠されていません、ちょうど別の場所にあります。これは、カッコではなく、関数名の左側にあります。

したがって、要約すると、同じ引数を取ることがないため、クラスのメンバー関数ポインタを別のクラスのメンバー関数に割り当てることはできません。

0

ALSは言ったもののほか、次の操作を割り当てることはできません。I_Workとして

tempy->pActionFunc = &Tree::I_Work; 

は、引数として暗黙のthisポインタを有しているため、引数リストは同じではありません。

0

すべてのメンバ関数には、関数シグネチャの一部である不可視のthisパラメータがあります。あなたが書くとき:

int(Apple::*pActionFunc)(void); 

内部コンパイラとしてそれを扱います:

int(*pActionFunc)(Apple* this); 

あなたはポインタに挿入しようとしている機能は、次の署名と同等を持っています

int I_Work(Tree* this); 

署名は一致しません。

関連する問題