組み込み型はきちんと初期化を
組み込み型は、intやfloat、charなどがそうです。
~組み込み型(変数)~
http://stlalv.la.coocan.jp/Variable.html#LOCAL
これらは、無茶苦茶な値(例えば-858993460とか)が入っているので、自分で初期値を代入する必要があります。
例外として
c++ライブラリのstring型やvector型はコンストラクタで空白なり0などで初期化されることが約束されています。しかし、いちいち配慮するのは余計なミスを起こすので、可能なら全て初期化しましょう。
コンストラクタでのメンバ変数の初期化
組み込み型の場合
デフォルトコンストラクタで初期化すると
1 2 3 4 5 6 7 8 | class Obj { public: Obj() { num = 0; //無茶苦茶な値が入っているのを0で初期化 } // コンストラクタ int num ; }; |
このようになると思います。
クラスの型の場合
コンストラクタ内で… 代入になる形(効率悪い)
同様にstring型の場合
1 2 3 4 5 6 7 8 | class Obj { public: Obj() { name = "hoge"; //既に空白で初期化されたところへの代入 } // コンストラクタ string name; //追加 }; |
となりますが、ここでのname変数への処理は代入になります。
なぜなら、name変数は代入される前にstringクラスのデフォルトコンストラクタで空白に初期化されているからです。
これにより、二度手間になって処理が無駄になります。
この[デフォルトコンストラクタ+代入]という二度手間を[引数付きのコンストラクタ]で初期化してくれるのが初期化子リストです。
初期化子リストで初期化(効率良い)
1 2 3 4 5 6 7 8 9 10 | class Obj { public: Obj() :name("hoge"), title("samp") //初期化子リスト { } //コンストラクタ string name; string title; //追加 }; |
コンストラクタ名前の後にコロンを置いて、変数名()の()の中に初期値を入れます。複数ある場合は、コンマで繋ぎます。
初期化子リストを使うと各変数のコンストラクタ、つまり、string型ならstringクラスの引数付きのコンストラクタで引数の値に初期化されます。
組み込み型も同様に
1 2 3 4 5 6 7 8 | public: Obj(int n) :num(n) //初期化子リスト { } //コンストラクタ int num; //追加 }; |
もちろん、Objコンストラクタの引数を使うことができます。
自作クラスも同様に
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class Birthday { public: Birthday(int m, int d) { //誕生日の月と日にちを引数にとるコンストラクタ month = m; day = d; } int month; //月 int day; //日 }; class Obj { public: Obj(int month, int day) :birthday(month, day) //ここでコンストラクタの引数を与える { } Birthday birthday; //この行だけではエラー 14行目必要(Birthdayコンストラクタは引数付きなので) }; |
自作クラスのコンストラクタが引数付きだけの場合、19行目で引数を与えない形で宣言するだけだとエラーがでます。かと言って、19行目で適当に引数を与えた
1 | Birthday birthday(6,24); //これはエラー 適当に6月24日で初期化 |
もエラーとなります。
つまり、
メンバ変数のクラスのコンストラクタが引数付きの場合は初期化子リストを使うしかない。
しかし、組み込み型(intやchar)とクラス型をいちいち区別するのはややこしいので、すべて初期化子リストで初期化しましょう。
まとめ
組み込み型は、c#やjavaと違い最初に無茶苦茶な値が入っているので初期化を!
処理を減らすために、初期化子リストを積極的に使おう。
1 2 3 4 5 6 7 8 9 10 | class Obj { public: //string型も()の中を空にして、メンバ変数を全て初期化子リストの入れるつもりで //(この場合、stringクラスのデフォルトコンストラクタが呼ばれる) Obj(int month, int day) :name(), title(), birthday(month, day) { string name; string title; Birthday birthday; }; |
参考
書籍「Effective C++ 第3版 4項」