2011-12-20 20 views
3

私はクラスのメンバへのポインタを必要とするとき、私はこれかもしれアドレスを取るために&演算子を使用する必要がない理由明確化

struct MyStruct 
{ 
    int foo(); 
}; 

int (MyStruct::*p)() = &MyStruct::foo; 

次私の質問があるとして、私は静的関数であれば無視されます。また、私はメンバーへのポインタが本当にポインタではないと聞いたことがある、誰かがそれを明確にすることはできますか?

答えて

6

静的関数の場合、通常の非メンバ関数ポインタと同じように機能します。関数名自体は暗黙的に関数ポインタに変換できます。

それは非静的メンバ関数だ場合、それはもはや非メンバ関数と同じことだ:

  1. それは隠されたthisパラメータがあります。
  2. 複数の継承シナリオでは、ポインタを基本クラスの1つに変換すると、別のアドレスへのポインタが生成されることがあります。これは、メンバ関数が継承されている場合、呼び出し前にポインタを調整する必要がある可能性があることを意味します。これはすでに、ポインタを使用してメンバ関数へのポインタを格納することを不可能にしています。

Raymond Chen wrote an interesting articleこれについては、詳細および例を挙げてください。

+0

は、非メンバ関数ポインタのアドレスはコンパイル時に解決できAgree.And。ただし、メンバー関数ポインタの場合、そのアドレスは実行時に解決されます(仮想関数など)。したがって、メンバ関数へのポインタを示すために単一のアドレスを使用することはできません – RolandXu

-2

なぜ私はそれが静的関数

た場合は、理想的に&メンバ関数の構文へのポインタの場合には、正しい は無視することができるアドレスを取るために&演算子を使用する必要があります省略することができます。私は、&構文があると思うかもしれない歴史的な条約のためです。

メンバーへのポインタが実際にポインタではないと聞いたことがありますか? はそれを明確にすることができますか?

これは間違っています。唯一の違いは、それらがメンバ関数へのポインタであることです。 class非スタティックメンバは、暗黙のthisポインタを引数として含んでいるため、特別なシグネチャを持っています。また、同じシグネチャを持つ通常の関数ポインタとは相互変換できません。 theoritically pがポイントしているコードの例で

int MyStruct::foo (MyStruct* const); 
+2

static_assert(!std :: is_pointer :: value、 "メンバ関数へのポインタはポインタ ");'。 –