C++ メンバ変数の初期化|コンストラクタでの初期化とメンバ宣言時の初期化

クラスのメンバ変数を初期化するには、コンストラクタ内で初期化を行う方法と、メンバ宣言時に初期化式を用いて直接初期化を行う方法の複数の方法を用いることができます。

/* コンストラクタ初期化子による初期化 */
struct T {
  int member;
  T() : member(9) {}
};

/* デフォルトメンバ初期化子による初期化 */
struct T {
  int member = 9;
};

目次

コンストラクタ初期化子によるメンバ変数の初期化

クラスのメンバ変数を初期化するにはコンストラクタ名() : メンバ変数名() {}という形式でコンストラクタを定義します。

struct T {
  int member;
  T() : member(9) {}
};

T().member; // 9

各メンバ初期化子をカンマで区切ることで複数のメンバを初期化することも可能となっています。またC++11以降では、丸括弧の代わりに波括弧を用いた初期化も可能となっています。

struct T {
  int a, b;
  T() : a(1), b{2} {}
};

T{}.a; // 1
T{}.b; // 2

これらの機能は主にメンバ初期化子リストという名前で知られています。またこの一連の記述はコンストラクタ初期化子とも呼ばれており、:記号とメンバ初期化子の並びによって構成されています。より細かな仕組みや仕様については、以下の記事が参考になります。

メンバ初期化子リスト #コンストラクタ初期化子/メンバ初期化子

デフォルトメンバ初期化子を用いたメンバ宣言

クラスのメンバ変数を宣言する際に=演算子や波括弧による初期化子を用いてメンバの初期化を行うことも可能です(C++11以降対応)。この機能は主にデフォルトメンバ初期化子(default member initializer)と呼ばれています。

struct T {
  int a = 1;
  int b{2};
  int c = {3};
  T() : c(9) {}
};

T().a; // 1
T().b; // 2
T().c; // 9(メンバ初期化子による初期化が優先される)

デフォルトメンバ初期化子を用いたメンバ宣言とコンストラクタ側メンバ初期化子による定義が重複した場合には、メンバ初期化子による初期化が優先されます。

より細かな説明や具体的な仕様については、以下の記事が参考になります。

メンバ初期化子 #メンバ宣言時に初期化子が指定された場合の挙動

ちなみにC++11では初期化子リストを用いた初期化との併用が行えないため注意が必要です。C++14以降であれば問題なく利用可能です。

struct T { int a = 1, b = 2; };
T a{};     // ok
T b{9};    // error: no matching constructor for initialization of 'T'
T c{9, 8}; // error: no matching constructor for initialization of 'T'
広告