C++の初期のバージョンでは、クラスのメンバーはコンストラクタ内で代入を通じて初期化されていました。その後、初期化リストを使用してコンストラクタの本体に入る前にクラスのメンバーを初期化する機能が追加され、特に定数メンバー、参照、およびパフォーマンスにとって重要です。
一部のクラスメンバー(例えばconstフィールドや参照)は、コンストラクタの本体内で代入によって初期化することができません—それらは作成時に設定される必要があります。さらに、代入を使用すると、最初にデフォルトコンストラクタが呼び出され、その後に代入が行われるため(2つの操作)、複雑なオブジェクトにとっては負担になる可能性があります:
class Example { const int x; std::string str; public: Example(int val, const std::string& s) : x(val), str(s) {} };
初期化リストを使用して、クラスのメンバーを即座に初期化します。これは特にconst、参照、デフォルトコンストラクタを持たないメンバークラス、STLクラスや大きな構造体を扱う際のパフォーマンスにとって重要です。
コードの例:
class Point { const int x; int& y; public: Point(int val, int& ref) : x(val), y(ref) {} };
重要な特徴:
コンストラクタの初期化リストの順序によってクラスメンバーの初期化順序を変更できますか?
いいえ!メンバーは、初期化リストの順序ではなく、クラス内での宣言の順序で常に初期化されます。この規則を無視すると、初期化の順序に関するエラーが発生します。
メンバー参照が初期化リストで初期化されていなくて、コンストラクタの本体内でのみ初期化された場合はどうなりますか?
コンパイルエラーが発生します!参照は、constフィールドと同様に、初期化リストで初期化する必要があります—それらはコンストラクタの本体に入る前に値を取得する必要があります。
初期化リストでconstメンバーを初期化した後に、コンストラクタの本体内でそれを変更できますか?
いいえ、初期化後に定数メンバーを変更することはできません—そのようなフィールドを変更しようとすると、コンパイルエラーが発生します。
コンストラクタ内でクラスのメンバーがコンストラクタの本体内で初期化されます。複雑なオブジェクトの場合、デフォルトコンストラクタの呼び出し、その後の代入、一時オブジェクトの破壊にリソースが費やされます。
長所:
短所:
すべてのメンバーが初期化リストで即座に初期化され、不必要な操作や不変フィールドの問題はありません。
長所:
短所: