0
#include <iostream>
using namespace std;

class Base {
    public:
        Base() {
            cout << "In Base" << endl;
            cout << "Virtual Pointer = " << (int*)this << endl;
            cout << "Address of Vtable = "
            << (int*)*(int*)this << endl;
            cout << "Value at Vtable = "
            << (int*)*(int*)*(int*)this << endl;
            cout << endl;
        }

        virtual void f1() { cout << "Base::f1" << endl; }
};

class Drive : public Base {
    public:
        Drive() {
            cout << "In Drive" << endl;
            cout << "Virtual Pointer = "
            << (int*)this << endl;
            cout << "Address of Vtable = "
            << (int*)*(int*)this << endl;
            cout << "Value at Vtable = "
            << (int*)*(int*)*(int*)this << endl;
            cout << endl;
        }

        virtual void f1() { cout << "Drive::f2" << endl; }
};

int main() {
    Drive d;
    return 0;
}

このプログラムの出力は

In Base
Virtual Pointer = 0012FF7C
Address of Vtable = 0046C08C
Value at Vtable = 004010F0

In Drive
Virtual Pointer = 0012FF7C
Address of Vtable = 0046C07C
Value at Vtable = 00401217

私の意見では、Drive インスタンスを初期化すると Drive クラスのコンストラクターだけが実行されますが、このプログラムでは、Base のコンストラクター内のコードも実行されます。そして、出力に従ってください。非常に奇妙なことがあります。インスタンスが 1 つ、仮想ポインターが 1 つしかありませんが、Vtable が 2 つあります。

4

1 に答える 1

1

継承されたクラスのコンストラクターを実行すると、そのスーパークラスのコンストラクターが自動的に実行されるためです。これは、Drive コンストラクターの最初の行で、コンパイラーが Base コンストラクターをアピールするようなものです。コンパイラの場合、Drive コンストラクタは次のようになります。

    Drive() {
        Base();
        cout << "In Drive" << endl;
        cout << "Virtual Pointer = "
        << (int*)this << endl;
        cout << "Address of Vtable = "
        << (int*)*(int*)this << endl;
        cout << "Value at Vtable = "
        << (int*)*(int*)*(int*)this << endl;
        cout << endl;
    }
于 2012-06-04T08:06:30.440 に答える