1

また、次のコードで関数の前に「&」を使用する必要があるのはなぜですか?

void (Mammal::*pFunc) () const=0;
pFunc=&Mammal::Move;

Move() は基本クラスの仮想関数で、pFunc はこのクラスの仮想関数へのポインタです。では、なぜ「&」を使用する必要があるのでしょうか。仮想関数のいくつかの特別なプロパティによると? それとも単に構文ですか?

4

3 に答える 3

1

通常の関数はそのアドレスだけで呼び出すことができるため、通常の関数へのポインターは単なるアドレスです。

非仮想関数は、そのアドレスだけで呼び出すこともできます (もちろん、thisコンパイラが使用するメカニズムによって渡されるポインターも)。そのため、非仮想関数へのポインターは単なるアドレスになる可能性があります。

仮想関数は、コンパイラ固有のメカニズム (通常は、オブジェクト内の既知のオフセットにある vtable; 関数のアドレスは、テーブルへのインデックス付けによって検出されます) によって検索される必要があり、仮想関数へのポインターには、オブジェクトの実際のタイプに応じて、呼び出す実際の関数を決定するために必要な情報。

ただし、メンバー関数へのポインターは、仮想関数と非仮想関数の両方を処理できる必要があるため、両方の適切なメカニズムに十分な余地があり、ランタイム呼び出しは格納されたデータをチェックして何をすべきかを判断します。

一部のコンパイラは代替手段を提供しています。仮想関数へのポインタをポインタに絶対に、積極的に格納しないことを約束するとコンパイラはより小さなポインタ表現を生成し、後で問題が発生することがわかります。あなたはその約束を破ります。

が必要な理由については、&必須です。Microsoft の初期の C++ コンパイラは&、クラス名を必要としませんでした (クラス名を必要としませんでした。省略した場合、現在のオブジェクトのクラスのメンバー関数へのポインターが取得されます)。彼らはルールを廃止することを提案することについて話しましたが、それはどこにも行きませんでした.

于 2013-08-10T15:50:05.313 に答える