C++11 から「デフォルトメンバ初期化子」というものができた。
デフォルトメンバ初期化子ってのは
class foo {
some_type variable = default_value;
};
こういうの。foo
のコンストラクタではなく、メンバ変数の宣言部に値を書くことができる。
私自身あまり使っていなかったんだけど、先日ふと存在を改めて認識して、使っていこうと思った。
思ったんだけど、じゃあ呼ばれる順序どうなっているの? ということで、試してみた。
まあソースコードを。
hoge.cpp
// clang++ -std=c++11 -Wall hoge.cp
# include <iostream>
int foo(char const *title) {
std::cout << title << "\n";
return 0;
}
struct dtype {
dtype() { std::cout << "dtype default-ctor\n"; }
dtype(char const *label) { std::cout << "dtype " << label << "\n"; }
};
struct btype {
btype() { std::cout << "btype default-ctor\n"; }
};
struct hoge {
int a = foo("a");
btype b;
int c = foo("c");
dtype d;
int e = foo("e-decl");
hoge() //
: e(foo("e-ctor")), // warning: field 'e' will be initialized after field 'd'
d("hoge ctor") //
{
std::cout << "in hoge::hoge\n";
}
};
int main() {
hoge h;
return 0;
}
メンバ変数は以下の通り:
|名前|宣言順|デフォ(略)子|初期化子リスト順|デフォルトctor|
|:-:|:-:|:-:|:-:|:-:|:-:|
|a
|1|✅|||
|b
|2|||✅|
|c
|3|✅|||
|d
|4||2||
|e
|5|✅|1||
出力結果は下記の通り:
a
btype default-ctor
c
dtype hoge ctor
e-ctor
in hoge::hoge
まあやる前からわかっていたけどそうなるよね。
で。
- 初期化方法がいろいろ混ざっていても、メンバ変数の宣言順に初期化される
- 初期化子リストにあるものは、初期化子リストのとおりに初期化される
- 初期化子リストにないものは、デフォルトメンバ初期化子の通りに初期化される
- デフォルトメンバ初期化子もなければ、デフォルトコンストラクタが呼ばれる
ということになっている。まあそうじゃないと困る。