C++ での動的配列のデストラクタ
プログラミング言語でプログラミングをしていると、コンストラクターとデストラクタについてよく耳にします。 コンストラクターは、クラスのオブジェクトを初期化するために使用される特別なメンバー関数ですが、デストラクターは、オブジェクトが破棄されるときに自動的に呼び出される特別な関数でもあります。
この記事では、C++ での動的配列のデストラクタについて詳しく説明します。
C++ での動的配列のデストラクタ
デストラクターは、クラスと同じ名前を持つ特別なメンバー関数であり、オブジェクトが破棄されるときに自動的に呼び出されます。
デストラクタ関数は、オブジェクトが破棄されるときに呼び出される最後の関数です。 コンストラクターによって作成されたオブジェクトが占有するメモリをクリーンアップします。
ただし、コンストラクタとデストラクタはどちらもクラスと同じ名前ですが、コンパイラが区別できるように書き方に違いがあります。 デストラクタは否定記号 (~
) の後にクラス名を使用して記述され、コンストラクタはクラス名だけで記述されます。
さらに、クラスのデストラクタは 1つしか存在できませんが、コンストラクタは複数存在できます。
オブジェクトが C++ で作成されるときはいつでも、ヒープ セクションでメモリを占有し、new
キーワードを使用してクラスのそのオブジェクトを動的に作成します。 同様に、delete
キーワードは、クラスの動的に作成されたオブジェクトを削除するために使用されます。
C++ でのデストラクタの必要性
メモリリークを避けるために、オブジェクトを削除する必要があります。 プログラマーが使用されていないヒープ内のメモリを削除するのを忘れると、メモリ リークが発生します。 このため、使用可能なメモリの量が減少するため、コンピューターのパフォーマンスが低下します。
さらに、デストラクタを使用してオブジェクトを明示的に削除しないと、実行時にプログラムがクラッシュします。
C++ でのデストラクタの例
それでは、delete
演算子を使用してクラスのオブジェクトを削除する方法の例をいくつか見てみましょう。
例 1:
最初の例では、new
演算子を使用してクラスのオブジェクトを動的に作成し、C++ の delete
キーワードを使用して明示的に削除します。
以下は、C++ で delete
演算子を使用するコード例です。
#include <iostream>
using namespace std;
class Employee {
public:
Employee() { cout << "Constructor of Employee class was called!\n"; }
~Employee() { cout << "Destructor of Employee class was called!\n"; }
void work() { cout << "Still Working!\n"; }
};
int main() {
Employee* emp = new Employee();
emp->work();
delete emp;
return 0;
}
出力:
Constructor of Employee class was called!
Still Working!
Destructor of Employee class was called!
上記の例では、コンストラクタ、デストラクタ、およびアクションに関する適切なメッセージを含む work
関数を持つクラス Employee
を作成しました。
main
関数では、new
キーワードを使用してクラス emp
のオブジェクトを作成し、work()
関数を呼び出しました。 その後、delete
演算子とオブジェクト名 emp
を使用して同じものを削除しました。
C++ でデストラクタを使用して動的配列を削除する
これまで、C++ で delete
キーワードを使用してクラスの単一のオブジェクトを削除する方法を見てきました。 それでは、C++ で動的配列またはオブジェクトの配列を削除する方法を見てみましょう。
この例では、new
キーワードを使用して C++ で動的配列を作成し、delete
演算子を使用してそれを削除します。
ただし、C++ で動的配列を削除する際に覚えておくべきことは、単に delete
ではなく、delete []
演算子を使用する必要があることです。 したがって、delete
演算子はクラスの単一のオブジェクトを削除するために使用されますが、動的配列またはオブジェクトの配列を削除するには、C++ で delete []
演算子を使用する必要があります。
それでは、コード例の助けを借りてそれを理解しましょう。
#include <iostream>
using namespace std;
class Employee {
public:
Employee() { cout << "Constructor of Employee class was called!\n"; }
~Employee() { cout << "Destructor of Employee class was called!\n"; }
void work() { cout << "Still working!\n"; }
};
int main() {
Employee* emp = new Employee[3];
emp[0].work();
emp[1].work();
emp[2].work();
delete[] emp;
return 0;
}
出力:
Constructor of Employee class was called!
Constructor of Employee class was called!
Constructor of Employee class was called!
Still working!
Still working!
Still working!
Destructor of Employee class was called!
Destructor of Employee class was called!
Destructor of Employee class was called!
このコード例では、前の例と同様のコードがありますが、今回は 3つの Employee
オブジェクトを作成し、C++ で delete []
演算子を使用してそれらを削除しました。
ただし、delete []
の代わりに delete
演算子を使用すると、実行時にプログラムがクラッシュします。 C++ での動的配列の削除をより明確に理解するために、その例も見てみましょう。
#include <iostream>
using namespace std;
class Employee {
public:
Employee() { cout << "Constructor of Employee class was called!\n"; }
~Employee() { cout << "Destructor of Employee class was called!\n"; }
void work() { cout << "Still working!\n"; }
};
int main() {
Employee* emp = new Employee[3];
emp[0].work();
emp[1].work();
emp[2].work();
delete emp;
return 0;
}
出力:
Error in `./example1.cpp': munmap_chunk(): invalid pointer: 0x000000000117f018 ***
timeout: the monitored command dumped core
/bin/bash: line 1: 33 Aborted timeout 15s ./0f6c05b9-ee09-44c3-acee-8ad8a882ac5e < 0f6c05b9-ee09-44c3-acee-8ad8a882ac5e.in
Constructor of Employee class was called!
Constructor of Employee class was called!
Constructor of Employee class was called!
Still working!
Still working!
Still working!
Destructor of Employee class was called!
したがって、上記の出力からわかるように、コンストラクターと関数 work
は 3つのオブジェクトすべてに対して呼び出されていますが、デストラクタは 1つのオブジェクトに対して 1 回しか呼び出されておらず、その後プログラムがクラッシュしました。
まとめ
この記事では、C++ での動的配列のデストラクタについて説明しました。 デストラクタは、オブジェクトが削除されるときに自動的に呼び出される特別なメンバー関数です。
delete
演算子を使用して、クラスのオブジェクトを削除します。 ただし、クラスの 1つのオブジェクトのみが削除されます。 動的配列またはオブジェクトの配列を削除するには、delete []
演算子を使用します。
演算子とその使用法については、この記事で適切な例を使用して説明しています。