2012-10-17 16 views
5

は、なぜ、すべてのデストラクタ、~D()~C()~B()~A()は、以下の例では呼ばれていますか? Aのこと:派生クラスのデストラクタが非仮想である場合、ベースクラスのデストラクタが派生オブジェクトで呼び出されるのはなぜですか?

一つだけの仮想デストラクタがあります。ここで

コードです:Aのデストラクタがvirtual宣言されると

#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; 
} 
+1

これが、言語の規則が何を言いたいのかということなのです。 – juanchopanza

答えて

7

、すべての派生クラスのデストラクタは、それらが明示的に宣言されていない場合でも、またvirtual ..ですので行動最も派生の最初のデストラクタ:あなたは、派生オブジェクトで期待されているまさに

+1

@spin_eight 'D'は' A'へのポインタを介してアクセスされます。これは削除が呼び出されたものです。 'A'のデストラクタが仮想でない場合、'〜A() 'だけが呼び出されます。自分で簡単に確認できます。 – juanchopanza

+0

はい、ありがとうございます! –

6

破壊の順序は、建設の正確逆 順に進む見ます10のクラスが呼び出され、その後、基本クラスのデストラクタが呼び出されます。

デストラクタは、仮想または仮想さえ純粋として定義することができます。あなたは派生クラスが基底クラスのポインタを使用して を破壊されることを期待する場合は、 仮想デストラクタを使用します。

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(); 

REFERENCE

+0

「純粋仮想」 - 実行時エラーを防止するときは、純粋な仮想デストラクタの本体を作成して、NULLptrだけでなくそのデストラクタの仮想テーブルにアドレスを割り当てる必要があります –

0

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

私は、彼らが唯一の今までの枠組みから派生メソッドをオーバーライドする必要がありましたので、キーワードが何をしたか知らなかった人にインタビューをしている理由ですので、彼らはすべての仮想(ため息)となりました。

関連する問題