6

以下の例で~D()、すべてのデストラクタ、、、が呼び出されるのはなぜ~C()ですか?~B()~A()

仮想デストラクタは、の1つだけですA

コードは次のとおりです。

#include<iostream>
using namespace std;

class A
{
public:
  virtual ~A()
  {
    cout<<"destruct A\n";
  }

};
class B:public A
{
public:
  ~B()
  {
  cout<<"destruct B\n"; 
  }
};
class C:public B
{
public:
  ~C()
  {
    cout<<"destruct C\n";
  }
};
class D:public C
{
public:
   ~D()
   {
     cout<<"destruct D\n"; 
   }
};

int main()
{
    A* ptr = new D();
    delete ptr;
    return 0;
}
4

3 に答える 3

7

Aのデストラクタが宣言されると、明示的に宣言されていなくてvirtualも、すべての派生クラスのデストラクタもvirtual宣言されます。したがって、表示される動作はまさに期待どおりです。

于 2012-10-17T05:33:47.533 に答える
7

派生オブジェクトの破棄順序は、構築の逆の順序になります。最初に、最も派生したクラスのデストラクタが呼び出され、次に基本クラスのデストラクタが呼び出されます。

デストラクタは、仮想または純粋な仮想として定義できます。基本クラスへのポインタを介して派生クラスが破棄されることが予想される場合は、仮想デストラクタを使用します。これにより、最も派生したクラスのデストラクタが確実に呼び出されます。

A* b1 = new B;//if A has a virtual destructor
delete b1;//invokes B's destructor and then A's

A* b1 = new B;//if A has no virtual destructor
    delete b1;//invokes A's destructor ONLY

Aに仮想デストラクタがない場合、タイプAのポインタを介してb1を削除すると、Aのデストラクタが呼び出されるだけです。この場合、Bのデストラクタの呼び出しを強制するには、Aのデストラクタを仮想として指定する必要があります。

virtual ~A();

参照

于 2012-10-17T05:45:05.910 に答える
0

@juanchopanzaが言ったように、ベースデストラクタを仮想と宣言することは、すべての子孫が仮想デストラクタを持っていることを意味します。この継承された仮想性は、デストラクタだけでなく、どのメソッドでも同じです。

そのため、フレームワークから派生したメソッドをオーバーライドするだけで、キーワードが何をするのかわからない人々にインタビューしました。そのため、彼らはすべて仮想的でした(ため息)。

于 2015-11-08T13:13:38.173 に答える