この質問-ほとんどの派生クラスのデストラクタでの純粋な仮想呼び出し-に続いて、いくつかのコードを試していくつかの構文をチェックし、連続するデストラクタが呼び出されると、それらが関連する仮想関数を呼び出すことを発見しました。次のコードを検討してください。
class Base
{
public:
virtual void Method() = 0;
};
class Derived : public Base
{
public:
~Derived()
{
Method();
}
virtual void Method()
{
cout << "D";
}
};
class DoubleD : public Derived
{
public:
~DoubleD()
{
Method();
}
virtual void Method()
{
cout << "DD";
}
};
int main(array<System::String ^> ^args)
{
DoubleD D;
DoubleD E;
return 0;
}
予想どおり、オブジェクトが破棄されると、正しいメソッドが呼び出されます (たとえば、最初に最も派生したもの、次に 2 番目に派生したもの)。
出力: DD D
私の質問は、なぜこれが機能するのですか? c'tor/d'tor で仮想関数を呼び出すことを意図していないため、仮想テーブルが正しく「巻き戻される」のはなぜですか。
たとえば、最も派生したものが機能する理由がわかります。これは、これが開始されたときの仮想関数ポインター テーブルの状態でした。しかし、Derived
のデストラクタが呼び出されたときに、そのクラスの の実装を指すようにテーブルが正しく設定されるのはなぜですかMethod
。
そのままにしておくのはどうでしょうか、それが良い場合は、値を NULL に設定してください。