(C++、MinGWの4.4.0、WindowsのOS)C++:バーチャルファンクションは "this"ポインタスコープの問題をどのように解決しますか?
すべてのことのラベル< 1>と< 2>を除き、コードにコメントしているが、私の推測です。あなたは、私がどこか間違っていると思う場合には、私を修正してください:
class A {
public:
virtual void disp(); //not necessary to define as placeholder in vtable entry will be
//overwritten when derived class's vtable entry is prepared after
//invoking Base ctor (unless we do new A instead of new B in main() below)
};
class B :public A {
public:
B() : x(100) {}
void disp() {std::printf("%d",x);}
int x;
};
int main() {
A* aptr=new B; //memory model and vtable of B (say vtbl_B) is assigned to aptr
aptr->disp(); //<1> no error
std::printf("%d",aptr->x); //<2> error -> A knows nothing about x
}
< 2>はエラーであり、明白です。なぜ< 1>は間違いがありますか?私はこの呼び出しで起こっていると思います:aptr->disp(); --> (*aptr->*(vtbl_B + offset to disp))(aptr)
aptr
は、暗黙的にメンバー関数へのポインタthis
です。内部disp()
std::printf("%d",x); --> std::printf("%d",aptr->x); SAME AS std::printf("%d",this->x);
< 2>はなぜ< 1>エラーを出さないのですか?
(私は特定とスタッフのvtableが実装されている知っているが、私はまだそれが質問をする価値があると思います)
okですが、 'this'はスライスされて、<1>の' A'だけが分かります。メンバ関数の中では、呼び出しは 'this-> whatEver'に解決されると思います。表示されているように暗黙のうちに渡された「this」は、Bオブジェクトの場合と同じではないので、私は混乱しています。 – ustulation
@ustulation:いいえ、 'this'は' B'型で、メソッド 'B :: disp()'は呼び出されたメソッドです。当然それ自身のメンバーである 'x'にアクセスできます。ここにスライスはありません。 –
実際のルールは_In C++です。動的ディスパッチは仮想メンバーにのみ使用されます_。あなたのルールはこれから、そしてその言語が変数を仮想として定義することを許さないという事実に従います。 –