デストラクタ徹底解説
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 24/104。
A destructor は、オブジェクトが破棄されたときに自動的に実行される特殊なメンバー関数です。その主な役割は、オブジェクトが存続期間中に取得したリソース(Dynamically 割り当てられたメモリ、ファイルハンドル、ネットワーク接続など)を解放することです。
The destructor は class と同じ名前を持ち、チルダ ~ を前置します。パラメーターを取らず、戻り値の型もありません。
class FileHandler {
std::string filename;
int* buffer;
public:
FileHandler(std::string name, size_t size)
: filename(name), buffer(new int[size]) {
std::cout << "Opening " << filename << "\n";
}
~FileHandler() {
delete[] buffer;
std::cout << "Closing " << filename << "\n";
}
};デストラクタは、次の状況で自動的に呼び出されます。
- Stack オブジェクトのスコープが終了する
- ヒープに割り当てられたオブジェクトに対して
deleteが呼び出される - 一時オブジェクトのライフタイムが終了する
void example() {
FileHandler f1("data.txt", 100); // コンストラクタが呼び出された
FileHandler* f2 = new FileHandler("log.txt", 50);
delete f2; // f2のデストラクタが呼び出された
} // f1のデストラクタが呼び出された(スコープ外になる)constructorとは異なり、classにはdestructorを1つだけ持たせることができます。destructorをオーバーロードすることはできません。
define しない場合、コンパイラーは特別な処理を何もしない default destructor を生成します。つまり、各 member を単純に破棄するだけです。リソースを管理する class では、メモリリークを防ぐために自分で destructor を記述する必要があります。
チャレンジ
簡単アクティブなユーザーセッションを追跡し、オブジェクトがスコープ外に出た場合や明示的に削除された場合など、オブジェクトが破棄されたときにデストラクタがリソースを自動的に Clean する仕組みを示すセッションマネージャーを作成しましょう。
コードを整理するために、2つのファイルを作成します。
Session.h:動的に割り当てられた data を持つアクティブなユーザーセッションを表すSessionclass を define します。class には次の要素を含めます。- private メンバー:
username(string)、sessionId(int)、ユーザーの操作を追跡するactivityLogという整数 array へのポインター、および array のサイズを示すlogSize - username、session ID、log size を受け取る constructor。activity log array を heap 上に allocate し、すべての elements を 0 に初期化して、
"Session <sessionId> started for <username>"を表示します - allocate されたメモリを解放し、
"Session <sessionId> ended for <username>"を表示する destructor - activity code を次に available なスロットに格納する
logActivity(int activityCode)method(current position は内部で追跡します) - 記録された activities の数を返す
getActivityCount()method - username を返す
getUsername()method
- private メンバー:
main.cpp:さまざまな状況での destructor の動作を示します。入力から username と log size を読み込み(それぞれ別の行に入力)、次の処理を行います。- curly braces
{ }を使用して scope block を作成し、その中で、入力された username、session ID101、入力された log size を使って stack に allocate されたSessionを作成します。codes1と2の2つの activities を記録し、"Stack session activities: <count>"を表示します。block が ends すると、destructor が automatically 実行されます。 - block の After に、
"Stack session destroyed"を表示します - username
"Guest"、session ID202、log size3を指定し、newを使用して heap に allocate されたSessionを作成します。code5の activity を1つ記録し、"Heap session activities: <count>"を表示してから、明示的にdeleteします。 - deletion の After に、
"Heap session destroyed"を表示します
- curly braces
この challenge では、destructor が呼び出される2つの主な方法を示します。stack object が scope を離れたときに automatically 呼び出される方法と、heap object を delete したときに手動で呼び出される方法です。どちらの経路でも、メモリリークを防ぐために、Dynamically allocate された activity log が適切に解放される必要があります。
#include "Session.h" を使用して、header file を main.cpp に include してください。
自分で試してみよう
#include <iostream>
#include <string>
#include "Session.h"
using namespace std;
int main() {
// 入力を読み取る
string username;
int logSize;
getline(cin, username);
cin >> logSize;
// TODO: 中括弧 { } でスコープブロックを作成する
// ブロック内:
// - 入力のユーザー名、セッションID 101、入力のログサイズでスタック割り当てされたSessionを作成する
// - コード1と2で2つのアクティビティをログする
// - Print "Stack session activities: <count>"
// ブロックが終了すると、デストラクタが自動的に実行される
// TODO: After the block, print "Stack session destroyed"
// TODO: newを使用してヒープ割り当てされたSessionを作成する
// - ユーザー名: "Guest"、セッションID: 202、ログサイズ: 3
// - コード5で1つのアクティビティをログする
// - Print "Heap session activities: <count>"
// - セッションを削除する
// TODO: After deletion, print "Heap session destroyed"
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタパラメータ付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ徹底解説Rule of Three / Five / Zero復習 - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () の演算子オーバーロード型変換演算子復習 - Matrixクラス自分で練習してみよう: C++オンラインコンパイラ