C++

C++ 初期化リストの初期化順序について

More than 1 year has passed since last update.

はじめに

そもそも初期化リストをご存じでしょうか?

main.cpp
class Hoge
{
    const int a;
    const int b;
    const int c;

public:
    Hoge():
        a(1),
        b(2),
        c(3)
    {}

};

基底クラスの引数もちコンストラクタを呼びたいとき、constメンバ変数を初期化したいときは必須になるでしょうし、メンバ変数を引数もちコンストラクタで初期化したいときもコンストラクタ本体で代入するのは一時変数が生成されてしまい、決して良くはないでしょう。

このように可能な限りメンバ変数の初期化は初期化リストで行うのがいいです。

なお、基底クラスのメンバ変数を派生先の初期化リストで初期化できない点には注意が必要です。

本題

初期化順序を知る

突然ですが次のコードを見てください

main.cpp
class Hoge
{

    int square;
    int num = 0;

public:
    Hoge(int n):
        num(n),
        square(num*num)
    {}

};

いっけん何の問題もないように見えますが実はバグです。

僕自身最初は初期化リストの書いた順番に初期化されると思っていましたが実はそうではありません。

メンバ変数の宣言した順番に初期化されるのです

つまり上の例でいうと
squareが初期化されたあとに、numが初期化されることになります。
num=0としていますが、ここでの初期化も同様です。

メンバ変数どうしが依存する初期化が必要な場合は宣言順に注意が必要です

まとめ

  • メンバ変数の初期化には初期化リストを使おう
  • 初期化リストの初期化順は宣言順