私はc ++で次のクラス定義を持っています:
struct Foo {
int x;
char array[24];
short* y;
};
class Bar {
Bar();
int x;
Foo foo;
};
そして、Barクラスの初期化子で「foo」構造体(およびそのすべてのメンバー)をゼロに初期化します。これはこの方法で行うことができます:
Bar::Bar()
: foo(),
x(8) {
}
...?
または、初期化子リストでfoo(x)は正確に何をしますか?
または、構造体はコンパイラから自動的にゼロに初期化されますか?
まず第一に、あなたはこれを読む必要があります! c ++ faq PODと集約について。あなたの場合、Foo
は実際にPODクラスであり、foo()
はvalue initializationです。
タイプTのオブジェクトを値で初期化するとは、次のことを意味します。
- tがユーザー宣言コンストラクター(12.1)を持つクラス型(9節)の場合、デフォルトのコンストラクター
Tが呼び出されます(Tにアクセス可能なデフォルトコンストラクターがない場合、初期化は不正な形式です)。- tがユーザー宣言コンストラクターを持たない非共用クラス型である場合、Tのすべての非静的データメンバーとベースクラスコンポーネントは値で初期化されます。
- tが配列型の場合、各要素は値で初期化されます。
- それ以外の場合、オブジェクトはゼロで初期化されます
はい、fooはゼロで初期化されます。 Bar
コンストラクターからこの初期化を削除した場合、foo
はdefault-initializedのみになることに注意してください。
オブジェクトに初期化子が指定されておらず、オブジェクトが(おそらくcv修飾された)非PODクラス型(またはその配列)である場合、オブジェクトはデフォルトで初期化されます。オブジェクトがconst修飾型である場合、基礎となるクラス型にはユーザーが宣言したデフォルトコンストラクターが必要です。 それ以外の場合、非静的オブジェクトに初期化子が指定されていない場合、オブジェクトとそのサブオブジェクト(存在する場合)の初期値は不定です;
標準C++では、Fooのctorを作成する必要があります。
_struct Foo {
Foo(int const a, std::initializer_list<char> const b, short* c)
: x(a), y(c) {
assert(b.size() >= 24, "err");
std::copy(b.begin(), b.begin() + 24, array);
}
~Foo() { delete y; }
int x;
char array[24];
short* y;
};
class Bar {
Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'},
new short(5)) { }
private:
int x;
Foo foo;
};
_
C++ 0xでは、統一された初期化リストを使用できますが、それでもFooにはdtorが必要です。
_class Bar {
Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'},
new short(5)} { }
~Bar() { delete[] foo.array; delete foo.y;}
}
private:
int x;
Foo foo;
};
_
foo
をデフォルトで初期化するには(Bar() : foo(), x(8) { }
として)Fooにデフォルトのctorを与える必要があります。