プログラミング言語 C++ において変数の宣言や new
式でコンストラクタに渡す引数が空の場合は引数リストを省略できます。 つまり、空の引数リストは書いても書かなくても挙動に差はありません。
class foo {
// 省略
};
int
main(void) {
// ↓ どっちでも同じ
foo a;
foo b{};
// ↓ どっちでも同じ
foo *c = new foo;
foo *d = new foo();
return 0;
}
しかしこの挙動には例外があります。 スカラ型や POD 型です。
POD (Plain Old Data) の厳密な定義はここでは述べませんが、おおざっぱに言えば C の構造体と互換性があるような型です。
#include <iostream>
// POD 型の定義
class foo {
public:
int data;
};
int main(void) {
static_assert(std::is_pod<foo>::value == true, "foo is not POD"); // 型 foo が POD 型であることを確認
foo a; // コンストラクタは呼び出されない
foo b{}; // コンストラクタが呼び出される
foo *c = new foo; // コンストラクタは呼び出されない
foo *d = new foo(); // コンストラクタが呼び出される
std::cout << a.data << std::endl; // 初期化されていないので不定。 未定義なのでやっちゃだめ!
std::cout << b.data << std::endl; // 0に初期化されている
std::cout << c->data << std::endl; // 初期化されていないので不定。 未定義なのでやっちゃだめ!
std::cout << d->data << std::endl; // 0に初期化されている
return 0;
}
定義した型が意図せず POD の要件を満たした場合 (そんなことはあまりありそうにないですが) にこの規則によってうっかり初期化漏れなどということがないように気を付けましょう。