C++ クラスコンストラクタ & デストラクタ

C++ クラス & オブジェクト

クラスのコンストラクタ

クラスのコンストラクタクラスの特別なメンバ関数であり、クラスの新しいオブジェクトを作成するたびに自動的に実行されます。

コンストラクタの名前はクラス名と完全に同じで、戻り値の型はありません(voidvoid でさえも持つことはできません)。コンストラクタは通常、メンバ変数に初期値を設定するために使用されます。

コンストラクタを明示的に定義しない場合、コンパイラは何も実行しないデフォルトコンストラクタを自動的に生成します。

以下の例は、コンストラクタの概念をよりよく理解するのに役立ちます。

例

#include <iostream> using namespace std; class Line { public: Line(); // コンストラクタの宣言 void setLength(double len); double getLength() const; private: double length; }; // コンストラクタの定義 Line::Line() { cout << "Object is being created" << endl; length = 0.0; // メンバ変数を明示的に初期化 } void Line::setLength(double len) { length = len; } double Line::getLength() const { return length; } // プログラムのメイン関数 int main() { Line line; // 長さを設定 line.setLength(6.0); cout << "Length of line : " << line.getLength() << endl; return 0; }

上記のコードをコンパイルして実行すると、次の結果が生成されます。

Object is being created
Length of line : 6

引数付きコンストラクタ

デフォルトのコンストラクタは引数を持ちませんが、必要に応じてコンストラクタに引数を持たせることもできます。これにより、オブジェクトを作成するときに初期値をオブジェクトに設定でき、個別に呼び出す必要はありません。set関数は、次の例のとおりです。

例

#include <iostream> using namespace std; class Line { public: Line(double len); // 引数付きコンストラクタの宣言 void setLength(double len); double getLength() const; private: double length; }; // コンストラクタの定義 Line::Line(double len) { cout << "Object is being created, length = " << len << endl; length = len; } void Line::setLength(double len) { length = len; } double Line::getLength() const { return length; } // プログラムのメイン関数 int main() { Line line(10.0); // オブジェクト作成時に初期長さを直接渡す // 初期長さを取得 cout << "Length of line : " << line.getLength() << endl; // 長さを再設定 line.setLength(6.0); cout << "Length of line : " << line.getLength() << endl; return 0; }

上記のコードをコンパイルして実行すると、次の結果が生成されます。

Object is being created, length = 10
Length of line : 10
Length of line : 6

初期化リストを使用してフィールドを初期化する

C++ では、次の使用を推奨していますメンバ初期化リストを使用してメンバ変数を初期化します。その構文は、コンストラクタのパラメータリストの後にコロン(:)を付け、その後ろに書きますメンバー変数名(初期値)。

以下の例では、: length(len)の意味は、渡されたパラメータを使用してlenメンバ変数を直接初期化することですlength。注意cout出力されるのはメンバ変数lengthであり、パラメータではありませんlen。これにより、メンバ変数が正しく代入されたことを直感的に確認できます:

Line::Line(double len) : length(len) { // この時点で length は初期化リストによって代入済みなので、length を出力して結果を確認する cout << "Object is being created, length = " << length << endl; }

上記の構文は、次に示す関数本体内で代入する書き方と同等であり、両者の出力結果は完全に同じです:

Line::Line(double len) { length = len; // パラメータ len をメンバ変数 length に代入する cout << "Object is being created, length = " << length << endl; }

2つの書き方の違いは、初期化リストが関数本体に入る前にメンバ変数の初期化を完了することです。一方、関数本体内の代入は、最初にデフォルト構築を行ってから代入するため、1ステップ多くなります。constconst メンバ、参照メンバ、およびデフォルトコンストラクタを持たないオブジェクトメンバにとって、初期化リストは唯一の初期化方法です。

クラス C に、初期化が必要な複数のフィールド X、Y、Z などがあるとします。各フィールドをカンマで区切るだけです。次のようになります:

C::C(double a, double b, double c) : X(a), Y(b), Z(c) { // その他の初期化ロジック(存在する場合) }

注意:初期化リスト内の各メンバの初期化順序は、クラス内での宣言順序によって決まり、記述順序ではありません。混乱を避けるため、宣言順序と一致させることをお勧めします。

クラスのデストラクタ

クラスのデストラクタはクラスの特別なメンバ関数であり、オブジェクトのライフサイクルが終了するとき(スコープを離れるか、またはdeletedelete されたときに)自動的に実行され、オブジェクトが占有するリソース(動的メモリやファイルハンドルなど)を解放するために使用されます。

デストラクタの名前はクラス名と完全に同じですが、先頭にチルダ(~)をプレフィックスとして付けます。デストラクタは値を返さず、引数も持つことができません。各クラスはデストラクタを1つだけ持つことができます。

以下の例は、デストラクタの概念をよりよく理解するのに役立ちます。

例

#include <iostream> using namespace std; class Line { public: Line(); // コンストラクタの宣言 ~Line(); // デストラクタの宣言 void setLength(double len); double getLength() const; private: double length; }; // コンストラクタの定義 Line::Line() { cout << "Object is being created" << endl; length = 0.0; } // デストラクタの定義 Line::~Line() { cout << "Object is being deleted" << endl; // 動的割り当てされたリソースがあれば、ここで解放します。例:delete[] data; } void Line::setLength(double len) { length = len; } double Line::getLength() const { return length; } // プログラムのメイン関数 int main() { Line line; // プログラム終了時に、デストラクタが自動的に呼び出される // 長さを設定 line.setLength(6.0); cout << "Length of line : " << line.getLength() << endl; return 0; }

上記のコードをコンパイルして実行すると、次の結果が生成されます。

Object is being created
Length of line : 6
Object is being deleted

C++ クラス & オブジェクト

その他の拡張