C++でクラスを(仮想デストラクタで)オーバーライドするとき、継承クラスでデストラクタを仮想として再度実装していますが、ベースデストラクタを呼び出す必要がありますか?
もしそうなら、私はそれがこのようなものだと思います...
MyChildClass::~MyChildClass() // virtual in header
{
// Call to base destructor...
this->MyBaseClass::~MyBaseClass();
// Some destructing specific to MyChildClass
}
私は正しいですか?
いいえ、デストラクタは構築の逆の順序で自動的に呼び出されます。 (基本クラスが最後です)。基本クラスのデストラクターを呼び出さないでください。
基本デストラクタを呼び出す必要はありません。派生デストラクタによって基本デストラクタが常に呼び出されます。 破壊の順序については、こちらの関連する回答をご覧ください 。
基本クラスに仮想デストラクタが必要な理由を理解するには、以下のコードを参照してください。
class B
{
public:
virtual ~B()
{
cout<<"B destructor"<<endl;
}
};
class D : public B
{
public:
virtual ~D()
{
cout<<"D destructor"<<endl;
}
};
あなたがするとき:
B *pD = new D();
delete pD;
次に、Bに仮想デストラクタがない場合、〜B()のみが呼び出されます。ただし、仮想デストラクタがあるため、最初に〜D()が呼び出され、次に〜B()が呼び出されます。
他の人が言ったことですが、派生クラスで仮想デストラクタを宣言する必要がないことにも注意してください。基本クラスで行うように、デストラクタを仮想で宣言すると、すべての派生デストラクタは、宣言するかどうかにかかわらず仮想になります。言い換えると:
struct A {
virtual ~A() {}
};
struct B : public A {
virtual ~B() {} // this is virtual
};
struct C : public A {
~C() {} // this is virtual too
};
いいえ。DerivedからBaseメソッドを明示的に呼び出して呼び出しを「チェーン」する他の仮想メソッドとは異なり、コンパイラーは、コンストラクターが呼び出された順序と逆の順序でデストラクターを呼び出すコードを生成します。
いいえ、基本クラスのデストラクタを呼び出すことはありません。他の人が指摘したように常に自動的に呼び出されますが、結果の概念実証は次のとおりです。
class base {
public:
base() { cout << __FUNCTION__ << endl; }
~base() { cout << __FUNCTION__ << endl; }
};
class derived : public base {
public:
derived() { cout << __FUNCTION__ << endl; }
~derived() { cout << __FUNCTION__ << endl; } // adding call to base::~base() here results in double call to base destructor
};
int main()
{
cout << "case 1, declared as local variable on stack" << endl << endl;
{
derived d1;
}
cout << endl << endl;
cout << "case 2, created using new, assigned to derive class" << endl << endl;
derived * d2 = new derived;
delete d2;
cout << endl << endl;
cout << "case 3, created with new, assigned to base class" << endl << endl;
base * d3 = new derived;
delete d3;
cout << endl;
return 0;
}
出力は次のとおりです。
case 1, declared as local variable on stack
base::base
derived::derived
derived::~derived
base::~base
case 2, created using new, assigned to derive class
base::base
derived::derived
derived::~derived
base::~base
case 3, created with new, assigned to base class
base::base
derived::derived
base::~base
Press any key to continue . . .
基本クラスデストラクタを仮想クラスとして設定すると、ケース3の結果はケース1および2と同じになります。
いいえ。自動的に呼び出されます。