コンストラクタ初期化リスト
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 22/104。
これまでのレッスンで、Player(std::string n, int h) : name(n), health(h) {}のようなコロン構文を見てきました。これはメンバー初期化子リストと呼ばれ、C++でメンバーを初期化する推奨される方法です。
initializer リストは constructor のパラメーターリストの後に、コロンで始まる形で現れます。各メンバーはその値で directly 初期化され、コンマで区切られます。
class Rectangle {
int width;
int height;
const int id;
int& reference;
public:
Rectangle(int w, int h, int i, int& r)
: width(w), height(h), id(i), reference(r) {
// コンストラクタの本体(空でもよい)
}
};コンストラクター本体での代入ではなく、なぜ初期化子リストを使うのでしょうか?代入を使うと、メンバーはまずデフォルト構築され、その後で新しい値が代入されます。初期化子リストを使うと、メンバーは正しい値で直接構築されるため、より効率的であり、場合によっては必須です。
特定のメンバーは、リストを使用して初期化する必要があります:
constメンバー - 構築後に代入できない
- 参照メンバー - 初期化時に束縛する必要があります
- デフォルトコンストラクターを持たないメンバー
class Player {
const int maxHealth; // イニシャライザリストを使用しなければならない
std::string name;
public:
// これは動作する
Player(int max, std::string n) : maxHealth(max), name(n) {}
// これはコンパイルできない:
// Player(int max) { maxHealth = max; } // エラー!
};メンバーは、初期化子リストの順序ではなく、class で declared された順序で initialized されます。混乱を避けるため、初期化子リストは常に宣言順に記述してください。
チャレンジ
簡単メンバーの initializer リストがいつ、なぜ不可欠なのかを示すゲームエンジン用の configuration システムを作成しましょう。initializer リスト構文を使って初期化 しなければならないメンバーを持つ GameConfig class を作成します。
コードを整理するために、2つのファイルを作成します。
GameConfig.h:ゲーム設定を格納するGameConfigclass を define します。この class には次のものを含めます。const std::string gameName:作成後に change できないゲームのタイトルconst int maxPlayers:constructor で固定される最大プレイヤー数int& difficultyRef:external な difficulty 設定への参照int screenWidthとint screenHeight:display 設定用の通常のメンバー- 必要なすべてのパラメーターを受け取り、initializer リストを使ってすべてのメンバーを初期化する constructor。initializer リストは、class 内でメンバーが定義されている順序に従う必要があります
- 次の形式で configuration を出力する
display()メソッド:Game: <gameName> Max Players: <maxPlayers> Difficulty: <difficultyRef value> Resolution: <screenWidth>x<screenHeight>
main.cpp:input から configuration 値を読み取り、GameConfig オブジェクトを作成します。次の処理が必要です。- game name(string)、max players(int)、difficulty(int)、width(int)、height(int)を input から読み取ります。それぞれ別の行に入力されます
- config が参照する difficulty 用のローカル
int変数を作成します - initializer リスト constructor を使って
GameConfigオブジェクトを作成します - 初期 configuration を表示するために
display()を Call します - difficulty 変数を directly 変更します(2倍します)
"After difficulty change:"を出力します- reference が更新後の値を反映することを示すため、もう一度
display()を Call します
この challenge は initializer リストが重要である理由を示します。const メンバーと reference メンバーは、constructor body で代入することが cannot です。これらはリスト内で初期化する必要があります。reference メンバーは、元の変数への change が config オブジェクトを通じてどのように反映されるかも示します。
#include "GameConfig.h" を使って header ファイルを main.cpp に include してください。
自分で試してみよう
#include <iostream>
#include <string>
#include "GameConfig.h"
using namespace std;
int main() {
// 入力値を読み取る
string gameName;
getline(cin, gameName);
int maxPlayers;
cin >> maxPlayers;
int difficulty;
cin >> difficulty;
int width;
cin >> width;
int height;
cin >> height;
// TODO: イニシャライザリストコンストラクタを使用してGameConfigオブジェクトを作成する
// コンストラクタは次を受け取る必要があります: gameName, maxPlayers, difficulty (参照渡し), width, height
// TODO: display()を呼び出して初期設定を表示する
// TODO: difficulty変数を直接変更する(2倍する)
// TODO: Print "After difficulty change:"
// TODO: display()を再度呼び出して更新された設定を表示する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタパラメータ付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ徹底解説Rule of Three / Five / Zero復習 - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () の演算子オーバーロード型変換演算子復習 - Matrixクラス自分で練習してみよう: C++オンラインコンパイラ