Menu
Coddy logo textTech

コンストラクタ初期化リスト

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 されます。混乱を避けるため、初期化子リストは常に宣言順に記述してください。

challenge icon

チャレンジ

簡単

メンバーの initializer リストがいつ、なぜ不可欠なのかを示すゲームエンジン用の configuration システムを作成しましょう。initializer リスト構文を使って初期化 しなければならないメンバーを持つ GameConfig class を作成します。

コードを整理するために、2つのファイルを作成します。

  • GameConfig.h:ゲーム設定を格納する GameConfig class を define します。この class には次のものを含めます。
    • const std::string gameName:作成後に change できないゲームのタイトル
    • const int maxPlayers:constructor で固定される最大プレイヤー数
    • int& difficultyRef:external な difficulty 設定への参照
    • int screenWidthint 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;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: C++オンラインコンパイラ