メンバ変数はコンストラクタの初期化子リストで初期化すべき

2022/10/31に公開

概要

C++でクラス内のメンバ変数の初期化方法というと以下の2種類があるがどちらが良いかを調べてみた。

  1. コンストラクタの定義内で各メンバ変数に初期値を設定
  2. コンストラクタの初期化子リストで初期化

結論

2の「コンストラクタの初期化子リストで初期化」する方が良い。

詳細

例えばnameとageというメンバ変数が定義されているPersonクラスがあった場合、これらのメンバ変数を1のコンストラクタの定義内で各メンバ変数に初期値を設定する方法だと以下のように書く。

class Person
{
    std::string name;
    int age;
    Person()
    {
        name = "hoge";
        age = 20;
    }
};

この方法でもnameとageについては意図した値で初期化は一応してくれるので、処理に大きな問題があるという訳ではない。だがC++では以下のような処理順で処理されるので、初期化した後のコンストラクタ内の処理でただ値を代入しているような形になってしまう。

<処理順>

  1. クラスの各メンバの初期化処理実行(メンバのコンストラクタのコール等)
  2. コンストラクタ内の処理実行

コンストラクタの初期化子リストを使えば、指定した初期値で1の初期化処理が走るので2の初期化後のムダな代入処理が不要になる。
よって、以下のようにコンストラクタの初期化子リストでやる方が良い。

class Person
{
    std::string name;
    int age;
    Person() : name("hoge"),age(20)
    {
    }
};

補足

C++11以降では以下のようにNSDMI(Non-static data member initializers)という方法でメンバの初期化を行うこともできるようになっている。

class Person
{
    std::string name = "hoge";
    int age = 20;
};

これはこれで良さそうだが、cppreference.comのサイトを見ると、色々動作に仕様細かいのありそうなので、こちらは勉強してまた別記事で書こうと思う。

Discussion