2

仮想デストラクタを使用するタイミングと理由について、少し混乱しています。

class Q { 
private: 
    int i; 
    int *pi; 
    int *p; 
public: 
    Q(int k); 
    print(); 
    ~Q() {delete pi; delete p;} 
}; 
class DQ : public Q 
{
private: 
    int *pd; 
public: 
    DQ(); 
    ~DQ(); 
};

主に私が

Q *p = new DQ();

p を削除すると、Q のデストラクタのみが呼び出されます。

しかし、これらのケースのそれぞれで何が起こるか:

  1. ~Q() のみが仮想ですが、~DQ() は仮想ではありませんか?
  2. ~DQ() のみが仮想ですが、~Q() は仮想ではありませんか?
  3. ~Q() は仮想で ~DQ() は仮想ですか?
4

3 に答える 3

4

1.)~Q()が仮想の場合、~DQ()書き込みかどうかに関係なく仮想virtualであるため、両方のデストラクタが呼び出されます

2.) 呼び出しdelete p;は未定義の動作です (おそらくQのデストラクタのみを呼び出しますが、未定義であるため、クラッシュしたり、さまざまなことを実行したりする可能性があります)。仮想性は上ではなく下に伝播します。

3.) 明示的に記述したことを除いて、#1 と同じケースですvirtual(ちなみに、これは良い習慣です)。両方のデストラクタが呼び出されます

于 2013-02-07T18:07:46.073 に答える
2

仮想デストラクタを使用するタイミングと理由について、少し混乱しています。

オブジェクトをポリモーフィックに削除するには、基本クラスに仮想デストラクタが必要です。つまり、基本型へのポインターを介して派生型のオブジェクトを削除します。

Q *p = new DQ();メインで a を割り当ててp を削除すると、Q のデストラクタのみが呼び出されることを理解しています。

いいえ、未定義の動作が発生します。Q のデストラクタを呼び出すか、上司に侮辱的な電子メールを送信する可能性があります。

~Q() のみが仮想ですが、~DQ() は仮想ではありませんか?

それ無理。関数がクラス内で仮想的である場合、派生クラスでも仮想的です。

~DQ() のみが仮想ですが、~Q() は仮想ではありませんか?

DQ次に、へのポインターを介して型のオブジェクトを削除することはできませんQ。試してみると、未定義の動作が発生します。しかし、 から別のクラスを派生させると、その仮想デストラクタのおかげで( ではなくDQ)へのポインタを介してそれらを削除できます。DQ Q

~Q() は仮想で ~DQ() は仮想ですか?

その後、すべてがうまくいき、基本クラスのポインターを介してオブジェクトを安全に削除できます。

于 2013-02-07T18:08:08.790 に答える
1

1. ~DQ() と ~Q() の両方が ~DQ()、~Q() の順に呼び出されます。2. ~Q() のみが呼び出されます。3. ~DQ() と ~Q() の両方が呼び出されます。

于 2013-02-07T18:09:53.070 に答える