1. ホーム
  2. c++

[解決済み] サブクラスへのポインタのdeleteは、ベースクラスのデストラクタを呼び出しますか?

2022-04-23 13:08:49

質問

私は class A そのフィールドの1つにヒープメモリアロケーションを使用します。クラス A はインスタンス化され、別のクラス ( class B .

クラスBのオブジェクトを使い終わったら delete デストラクタを呼び出すのでしょう。しかし、これはクラスAのデストラクタも呼び出すのでしょうか?

編集する

回答からすると、そうなりますね(間違っていたら編集してください)。

  1. delete BのインスタンスのB::~B()を呼び出します。
  2. を呼び出す。 A::~A();
  3. A::~A べき 明示的に delete A オブジェクトのヒープで割り当てられたすべてのメンバ変数。
  4. 最後に、クラス B のインスタンスを保存しているメモリブロックがヒープに戻されます。 新しい が使われた場合、まずヒープ上にメモリブロックを確保し、次にコンストラクタを呼び出して初期化し、すべてのデストラクタを呼び出してオブジェクトを確定した後、オブジェクトが存在したブロックをヒープに返します。

解決方法は?

Aのデストラクタは、そのライフタイムが終了したときに実行されます。もし、そのメモリを解放してデストラクタを実行させたいなら、それがヒープに割り当てられたものであれば、それを削除しなければなりません。スタック上に確保されている場合は、自動的に削除されます (つまり、スコープ外に出たときです。RAII を参照してください)。 もしそれがクラスのメンバ(ポインタではなくフルメンバ)であれば、それを含むオブジェクトが破壊されるときに起こります。

class A
{
    char *someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { delete[] someHeapMemory; }
};

class B
{
    A* APtr;
public:
    B() : APtr(new A()) {}
    ~B() { delete APtr; }
};

class C
{
    A Amember;
public:
    C() : Amember() {}
    ~C() {} // A is freed / destructed automatically.
};

int main()
{
    B* BPtr = new B();
    delete BPtr; // Calls ~B() which calls ~A() 
    C *CPtr = new C();
    delete CPtr;
    B b;
    C c;
} // b and c are freed/destructed automatically

上記の例では、すべてのdeleteとdelete[]が必要です。 そして、使っていないところでは、deleteは必要ない(というか、使える)。

auto_ptr , unique_ptrshared_ptr などは、このライフタイム管理をより簡単にするために最適です。

class A
{
    shared_array<char> someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { } // someHeapMemory is delete[]d automatically
};

class B
{
    shared_ptr<A> APtr;
public:
    B() : APtr(new A()) {}
    ~B() {  } // APtr is deleted automatically
};

int main()
{
    shared_ptr<B> BPtr = new B();
} // BPtr is deleted automatically