3

私たちが持っていると仮定します:

class A {
protected:
    int* iArr;
    float *fArr;
public:
    A(int* iArr,float *fArr);
    ~A();
}

class B : public A {
private:
    double *dArr;
public:
    B(int* iArr,float *fArr,double *dArr);
    ~B();
}

私の直感は、B のデストラクタのみを呼び出すということでしたが、Visual C++ で実行すると、B のインスタンスを破壊すると、A と B の両方のデストラクタが呼び出されることがわかりました。

では、派生クラスでデストラクタを記述する正しい方法は何ですか? 親クラスがすべてを削除することを常に想定する必要がありますが、派生クラスだけが持っているものは何ですか?

編集

  1. もしそうなら、子がオーバーライド関数のみで親クラスを拡張している場合、それは子のデストラクタを空のままにしておくことを意味しますか?

  2. それを変更したい場合はどうすればよいですか?子デストラクタのみを呼び出したい場合はどうすればよいですか? それを行う方法はありますか?

4

2 に答える 2

6

一言で言えば、そうです。

親クラスのデストラクタは常に自動的に呼び出されます。その役割は、親クラスが使用するすべてのリソースを解放することです。

子クラスのデストラクタは、子クラスに固有のものを解放する責任があります。

さらに、親クラスへのポインタを介して子クラスのインスタンスを削除する場合は、親クラスのデストラクタを仮想にする必要があります。仮想デストラクタを使用する場合を参照してください。

于 2012-06-10T18:41:10.650 に答える
4

A のデストラクタは仮想でなければなりません。あなたの問題は、次のことを行う場合です。

A* b = new B( iArr, fArr, dArr );
delete b;

次に、B としてインスタンス化されている間、B は A のように見え、B のデストラクタは仮想テーブルにエントリを持たないため、B のデストラクタは呼び出されません。 )

編集:

1 の答えとして、デストラクタを空のままにしておくか、定義できませんでした。

2の答えとして、あなたは本当にそれをすることはできません。「Destroy」または基本クラスのデストラクタから呼び出されるものと呼ばれる仮想保護関数を使用することをお勧めします。それが、あなたの言うように破壊を制御する唯一の方法だと思います。

于 2012-06-10T18:45:38.327 に答える