デフォルトコンストラクタ
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 18/104。
デフォルトコンストラクタは、引数なしで呼び出すことができるコンストラクタです。初期値が指定されていない場合にオブジェクトを初期化します。すべてのクラスには、有効なデフォルト状態でオブジェクトを作成する方法が必要です。
コンストラクタを定義しない場合、コンパイラは、プリミティブ型に対しては何もしない一方で、メンバオブジェクトに対してはデフォルトコンストラクタを呼び出す暗黙のデフォルトコンストラクタを生成します。
class Player {
int health;
int score;
public:
Player() { // デフォルトコンストラクタ
health = 100;
score = 0;
}
};
Player p1; // デフォルトコンストラクタを呼び出す
Player p2{}; // これもデフォルトコンストラクタを呼び出すコンストラクタ(引数付きコンストラクタなど)を定義すると、コンパイラはデフォルトコンストラクタを自動生成しなくなります。引き続き必要な場合は、明示的に定義する必要があります。
class Enemy {
int damage;
public:
Enemy(int d) : damage(d) {} // 引数付きコンストラクタのみ
};
Enemy e1(10); // 動作する
Enemy e2; // エラー!デフォルトコンストラクタがありませんモダンなC++では、= defaultを使用して、コンパイラによって生成されるデフォルトコンストラクタを明示的に要求することができます:
class Item {
int id;
public:
Item() = default; // コンパイラがデフォルトコンストラクタを生成します
Item(int i) : id(i) {}
};デフォルトコンストラクタは、オブジェクトの配列を作成する場合や、引数なしで要素を構築する必要がある std::vector のようなコンテナで使用されるクラスにとって不可欠です。
チャレンジ
簡単デフォルトコンストラクタがオブジェクトを有効な初期状態に初期化する方法を実証する、シンプルなカウンターシステムを構築しましょう。
コードを整理するために、2つのファイルを作成します。
Counter.h: カウント値を追跡するCounterクラスを定義します。クラスには以下を含める必要があります。- プライベートな
count属性(整数) - カウンターを識別するためのプライベートな
name属性(文字列) countを0に、nameを"Unnamed"に初期化し、"Counter created: <name>"と出力するデフォルトコンストラクタ- カウントを1増やす
increment()メソッド - 現在のカウントを返す
getCount()メソッド - カウンターの名前を返す
getName()メソッド
- プライベートな
main.cpp: オブジェクトを異なる方法で作成したときに、デフォルトコンストラクタが機能することを実証します。入力からカウンターを何回インクリメントするかを示す数値を読み取り、以下の処理を行います。- 直接初期化を使用してCounterを作成する:
Counter c1; - 波括弧初期化を使用して別のCounterを作成する:
Counter c2{}; - 入力で指定された回数だけ
c1をインクリメントする - c1 について
"<name>: <count>"と出力する - c2 について
"<name>: <count>"と出力する
- 直接初期化を使用してCounterを作成する:
デフォルトコンストラクタのおかげで、両方のカウンターは 0 から始まりますが、インクリメントされるのは c1 だけです。これにより、オブジェクトがどのように作成されたかに関わらず、デフォルトコンストラクタによってすべてのオブジェクトが予測可能で有効な状態から始まることが示されます。
main.cpp で #include "Counter.h" を使用してヘッダーファイルをインクルードしてください。
チートシート
デフォルトコンストラクタは、引数なしで呼び出すことができるコンストラクタです。初期値が提供されない場合にオブジェクトを初期化します。
class Player {
int health;
int score;
public:
Player() { // デフォルトコンストラクタ
health = 100;
score = 0;
}
};
Player p1; // デフォルトコンストラクタを呼び出す
Player p2{}; // これもデフォルトコンストラクタを呼び出すコンストラクタを一つも定義しない場合、コンパイラは暗黙のデフォルトコンストラクタを生成します。しかし、一度でもコンストラクタ(引数付きコンストラクタなど)を定義すると、コンパイラはデフォルトコンストラクタを自動的に生成しなくなります。
class Enemy {
int damage;
public:
Enemy(int d) : damage(d) {} // 引数付きコンストラクタのみ
};
Enemy e1(10); // 動作する
Enemy e2; // エラー!デフォルトコンストラクタがない= default を使用して、コンパイラが生成するデフォルトコンストラクタを明示的に要求することができます。
class Item {
int id;
public:
Item() = default; // コンパイラがデフォルトコンストラクタを生成する
Item(int i) : id(i) {}
};デフォルトコンストラクタは、オブジェクトの配列を作成する場合や、std::vector などのコンテナで使用されるクラスにとって不可欠です。
自分で試してみよう
#include <iostream>
#include "Counter.h"
using namespace std;
int main() {
// インクリメントする回数を読み込む
int n;
cin >> n;
// TODO: 直接初期化を使用して Counter を作成する: Counter c1;
// TODO: ブレース初期化を使用して別の Counter を作成する: Counter c2{};
// TODO: n で指定された回数だけ c1 をインクリメントする
// TODO: c1 に対して "<name>: <count>" を出力する
// TODO: c2 に対して "<name>: <count>" を出力する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタ引数付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ詳解Rule of Three / Five / Zeroまとめ - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () 演算子のオーバーロード型変換演算子まとめ:Matrix クラス