2016-08-18 3 views
0

私は、次のようないくつかの奇妙なコードに出くわした:サブクラスのデストラクタが呼び出された場合は、そのベースクラスのデストラクタの呼び出しを停止できますか?

class B { 
    int* ab; 
    ///... 
    ~B() { /// not virtual 
     delete ab; 
    } 
    ///... 
} 

class D : public B { 
    int* ad; 
    ///... 
    ~D() { 
     delete ab; 
     delete ad; 
    } 
    ///... 
} 

しかし、私の意見では、サブクラスのデストラクタは間違いなくその基底クラスのデストラクタを呼び出します。だから、私は、サブクラスがその基本クラスによって割り当てられたリソースを解放する必要はないと思う。したがって、Dのデストラクタにdelete abを追加する必要はありません。悪いのは、deleteオブジェクトが2回間違っていることです。

しかし、このコードは私たちのシステムでは非常に長い間働いていて、私たちのテストケース全体に合格しています。このような奇妙な実装には他に何か考慮すべき点がありますか?

サブクラスのデストラクタが呼び出された場合、何が起きても基本クラスのデストラクタは後で呼び出されます。
サブクラスのデストラクタの実行後、ベースクラスのデストラクタの実行を停止する方法はありますか?

+1

'〜B'は'〜D'の後に呼び出されます。このコードは、 'ab'が2回削除されるというバグがあります。 ( 'D'が削除された場合) –

+0

コンパイル時にエラーが発生するか、実行時にエラーが発生するのはなぜですか@ MM –

+2

[未定義の動作](http://stackoverflow.com/a/4105123/1505939) –

答えて

2

Dインスタンスが破棄された場合、Bクラスのデストラクタが呼び出されるのは間違いありません。 D dtorのdelete ab;への呼び出しはバグです。

Bのdtorが仮想ではないため、Bポインタを使用してDのインスタンスを削除できないため、このコードで考慮する必要があります。

DのDTORはどちらの場合も正しくないため、間違いなく変更する必要があります。多態的にクラスの階層を使用する予定がある場合は、B DTORを仮想に変更する必要があります。

+0

ああ、サブクラスのデストラクタが呼び出されると、そのベースクラスのデストラクタも呼び出されます?@Dennis –

+0

@ YuanWenデストラクタを呼び出し、そのメンバーとベースクラスを構造の逆順で破棄すると、オブジェクトの破壊が発生します。 –

+0

基本クラスのデストラクタが仮想であるかどうかにかかわらず、@Dennis –

関連する問題