ホームに戻る
関連 :
デフォルトメンバ初期化子 const修飾の使い方
目次 :

コンストラクタ初期化子とは

コンストラクタの実処理に先立ってメンバ変数を初期化する際に用いる、初期化対象と値の対。
画像

コンストラクタ初期化子を用いる利点

以下に挙げる利点から、メンバ変数の初期化には原則としてコンストラクタ初期化子を用いることが望ましい。

処理が高速となる

画像
上記のクラス定義におけるインスタンス生成結果は一見変わらない。
しかし、コンストラクタ初期化子を用いない場合、上記の m_a = x; 文は、
  1. 変数 m_a を int 型のデフォルト値(不定)で「初期化」する
  2. 変数 m_a に x を 「代入」する
という二つの段階を経過するが、コンストラクタ初期化子を用いる場合は、
  1. 変数 m_a を xで 「初期化」する
となり、処理段階が減る。
特に、メンバ変数がクラス(または構造体、共用体)インスタンスで、コンストラクタの処理が重い場合に威力を発揮する。

「変数の初期化」と「それ以外の処理」を分離できる

コンストラクタ内にメンバ変数の初期化と、それ以外の処理が混在する場合、クラスが大きくなるにつれてそれらの峻別は難しくなる。
コンストラクタ初期化子を用いることで両者を分離できるため、コードの可読性向上にもつながる。

コンストラクタ初期化子を用いる必要がある場合

クラスの実装によっては、コンストラクタ初期化子を用いる以外の初期化が不可能となる。

メンバ変数がクラス、かつデフォルトコンストラクタが存在しない

以下のようなクラスを考える。
// 引数付きコンストラクタをもつCHogeクラス class CHoge { public: // (引数付き)コンストラクタ CHoge(int x) { (略) } }
// CHogeクラスをメンバにもつCFugaクラス class CFuga { private: CHoge m_cl_Hoge; //< CHogeクラスのインスタンス public: CFuga(int x) { m_cl_Hoge(x); //< CHogeクラスのインスタンスを初期化しようとしているが… : } }
上記のコードはエラーとなる
先述の通り、CFuga クラスのインスタンス生成時にはメンバ変数 m_cl_Hoge が 「デフォルトコンストラクタ(引数なしのコンストラクタ)」で初期化される が、
CHoge クラスには「引数なしのコンストラクタ」が存在しない ためである。
このように、 メンバ変数がクラス(または構造体)型かつ、デフォルトコンストラクタが存在しない場合は、コンストラクタ初期化子を用いる以外に初期化の手段は無い

以下、修正したコード。
// CHogeクラスをメンバにもつCFugaクラス class CFuga { private: CHoge m_cl_Hoge; //< Hogeクラスのインスタンス public: CFuga(int x) : m_cl_Hoge(x) //< 引数付きコンストラクタで初期化される { : } }

constメンバ変数の初期化

const修飾されたメンバ変数は、コンストラクタ初期化子を用いなければ初期化できない。(代入が許可されないため。)
constメンバ変数については、const修飾の使い方を参照のこと。

デフォルトメンバ初期化子との関係

C++11ではデフォルトメンバ初期化子が追加された。詳細はリンク先を参照。
struct T { int member = 9; //< (コンストラクタで初期化を行わなかった場合) member は 9 で初期化される };
これは、コンストラクタでメンバ変数の初期化を行わなかった場合にデフォルトで適用される初期値を指定できるもので、
デフォルトメンバ初期化子を用いると、メンバ変数を初期化するためだけにコンストラクタを定義する必要がなくなる。
但し、デフォルトメンバ初期化子を割り当てた場合でもコンストラクタでの初期化は有効であり、その場合はコンストラクタ初期化子の値が優先される。
これは関数におけるデフォルト引数と同様である。