2012-04-06 14 views
2

私は関数ポインタが関数のアドレスを格納していることを知っています。ここで、関数ポインタが格納するアドレスは

int fun(int x){ 
//return something 
} 
int (pfun*)(int)=&fun; 

int main(){ 

std::cout << &fun << "\n"; // this print out 1 
std::cout << fun << "\n" ; // this print out 1 
std::cout << &pfun << "\n"; // this print out 0x0022ff40 
std::cout << pfun << "\n" ; // this print out 1 

} 



は、だから私の質問は以下のとおりです。

1)あれば楽しい()でも楽しみをポイントしていpfunすることができますどのようにアドレスを持っていません()。
2)たとえば、実行時にポインタ関数を使用するときの動的バインディングでは、コンパイラはpfunの値を0Xのような実際のポインタに変更するのですか?実行時に、コンパイル後に名前が存在しないのでどの関数を呼び出すのかを知るでしょうか?

答えて

5

表現fun&funは同じ意味を持ちます。 &pfunはポインタのアドレスで、変数のアドレスです。

は今の質問は、なぜ 1 ...よく、答えは std::ostreamと関数ポインタを取る何過負荷に operator<<がないことであるので、コンパイラがあることを起こる、既存のオーバーロードの中で最高の試合を見つけようとします bool(関数ポインタは暗黙的に boolに変換可能です)。関数ポインタは、関数ポインタがnullの場合にのみ falseに変換されます(そうではありません)。 trueの値は、最終的に 1として出力されます(これは std::cout << std::boolalpha << funで、これは trueと印刷されます)。

(このプロセスで)関数の実際のアドレスを取得する場合は、キャストを強制的にvoidポインターにして結果を出力することができます。これは技術的には正確ではないかもしれませんが、1とは異なる数値が与えられます。値は実行ごとに異なり、基本的に意味がありません。

+0

正しく覚えていれば、 'void *'への関数ポインタのキャストは許されません。標準で明示的にそう言われていますが...具体的にはメンバ関数のポインタだったので、チェックする必要があります。 –

+0

@Als:答えに技術的に正しい*コメントはありません。事実、IIRCはほとんどのアーキテクチャで動作しますが、標準では関数やデータのポインタのサイズが異なるため元の結果を生み出す...そして、私が言及したように、それが価値を生み出すプラットフォームでさえも、それは役に立たない。 –

+0

'void *'への関数ポインタを明示的に記述することは無効であり、メンバ関数ポインタにのみ適用できますか?またはフリースタンディング関数ポインタ? –

1

operator<<は、関数ポインタを印刷するための適切なオーバーロードを持っていません。代わりにこれを試してください。 &funpfunに格納された値に相当し、彼らの3は同じ出力が得られていることも不思議ではない:

#include <iostream> 

void fun() {} 

void (*pFun)() = &fun; 

int main() 
{ 
    std::cout << (void*)pFun << "\n"; 
} 
関連する問題