C++では、クラスのメンバーの初期化順序は、クラス本体の宣言順序の通りで行われ、コンストラクタの初期化リストで指定された順序ではありません。
例:
struct Foo { int a; int b; Foo() : b(2), a(b) {} };
この例では、まず、未定義の変数bの値でaが初期化されます。なぜなら、最初にaが初期化され、その後にbが初期化されるからです。このため、aは2になりません。
正しい方法は、初期化の際に、上に宣言されているメンバーだけを参照するか、定数を使用することです。
コンストラクタの初期化リストで初期化順序が宣言と異なる場合、クラスのメンバーはどのような順序で初期化されますか?
回答: いつも最初に初期化されるのは、クラス内で最初に宣言されたメンバーであり、コンストラクタの初期化リストの順序にかかわらずです。これは、クラスメンバー間の相互依存性に関するエラーを引き起こす可能性があります。
物語
複雑なクラスで、クラスメンバーへの参照を初期化する際に、他のメンバーが初期化されていない状態になった。初期化リストの順序は意味を持たないことが分かり、未初期化のメモリが使用される結果となった。特定のコンパイラと設定の下でのみソフトウェアがクラッシュした。
物語
依存メンバーの初期化順序を修正せずにクラスの中央に新しいメンバーを追加した結果、静的コード分析でのみ発見されたエラーが発生した。古い宣言順序のために変数が無効な値を取っていた。
物語
ライブラリの新しいバージョンがクラスのソースコードを変更し、メンバーの順序を変更したが、コンストラクタは変更しなかった。その結果、アプリケーション内のValuesが無効なデータで動作し、エンジニアは初期化順序に関するコンパイラの警告を見るまで原因を理解できなかった。