[解決済み] サブクラスへのポインタのdeleteは、ベースクラスのデストラクタを呼び出しますか?
2022-04-23 13:08:49
質問
私は
class A
そのフィールドの1つにヒープメモリアロケーションを使用します。クラス A はインスタンス化され、別のクラス (
class B
.
クラスBのオブジェクトを使い終わったら
delete
デストラクタを呼び出すのでしょう。しかし、これはクラスAのデストラクタも呼び出すのでしょうか?
編集する
回答からすると、そうなりますね(間違っていたら編集してください)。
-
delete
BのインスタンスのB::~B()を呼び出します。 -
を呼び出す。
A::~A();
-
A::~A
べき 明示的にdelete
A オブジェクトのヒープで割り当てられたすべてのメンバ変数。 - 最後に、クラス 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_ptr
と
shared_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
関連
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] インターフェースとベースクラス
-
[解決済み] ベースクラスのコンストラクタを呼び出す際のルールは?
-
[解決済み] ベースの仮想デストラクタを明示的に呼び出す必要がありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された