C ++での次のフレーズの意味は何ですか。
ゼロ初期化、
デフォルトの初期化、および
値の初期化
C ++開発者はそれらについて何を知っているべきですか?
C ++での次のフレーズの意味は何ですか。
ゼロ初期化、
デフォルトの初期化、および
値の初期化
C ++開発者はそれらについて何を知っているべきですか?
回答:
認識すべきことの1つは、「値の初期化」がC ++ 2003標準で新しく追加されたことです。これは、元の1998年の標準には存在しません(明確化以上の唯一の違いかもしれません)。標準から直接の定義については、Kirill V. Lyadvinskyの回答を参照してください。
operator new
これらのタイプの初期化のさまざまな動作と、それらが作動するタイミング(およびc ++ 98とC ++ 03が異なる場合)の詳細については、の動作に関する以前の回答を参照してください。
答えの要点は:
new演算子によって返されるメモリが初期化されることもあれば、更新する型がPODであるか、それがPODメンバーを含み、コンパイラー生成のデフォルトコンストラクターを使用しているクラスであるかによって異なる場合もあります。 。
- C ++ 1998では、ゼロとデフォルトの2種類の初期化があります。
- C ++ 2003では、3番目のタイプの初期化である値の初期化が追加されました。
控えめに言っても、それはかなり複雑であり、さまざまな方法が実行されるタイミングは微妙です。
VS 2008(VC 9またはcl.exeバージョン15.x)であっても、MSVCはC ++ 98の規則に従っていることに注意してください。
次のスニペットは、MSVCとDigital MarsがC ++ 98ルールに従っているのに対し、GCC 3.4.5とComeauはC ++ 03ルールに従っていることを示しています。
#include <cstdio>
#include <cstring>
#include <new>
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
int main()
{
char buf[sizeof(B)];
std::memset( buf, 0x5a, sizeof( buf));
// use placement new on the memset'ed buffer to make sure
// if we see a zero result it's due to an explicit
// value initialization
B* pB = new(buf) B(); //C++98 rules - pB->m is uninitialized
//C++03 rules - pB->m is set to 0
std::printf( "m is %d\n", pB->m);
return 0;
}
int
はありませんがm()
、3行目の値はmを初期化します。に変更int m;
する場合は重要ですB m;
。:)
A
とC
、この例で使用されていない(彼らは他のリンクの答えから引き継がれています)。C ++ 98とC ++ 03 は、方法A
とC
構造を説明するときに異なる用語を使用していますが、結果は両方の標準で同じです。struct B
結果が異なるだけです。
struct C { C() : m() {}; ~C(); B m; };
に変更すると、m.m
0になります。ただし、m
C ++ 03のようにdefault-initialise を実行するとm.m
、C ++ 98のように初期化されません。
C ++ 03標準8.5 / 5:
タイプTのオブジェクトをゼロ初期化するとは、次のことを意味します
。— Tがスカラータイプ(3.9)の場合、オブジェクトはTに変換された値0(ゼロ)に設定されます。
— Tが非共用クラス型の場合、各非静的データメンバーと各基本クラスサブオブジェクトはゼロで初期化されます。
— Tが共用体型の場合、オブジェクトの最初の名前付きデータメンバーはゼロで初期化されます。
— Tが配列型の場合、各要素はゼロで初期化されます。
— Tが参照型の場合、初期化は実行されません。タイプTのオブジェクトをデフォルトで初期化するとは、次のことを意味します
。— Tが非PODクラスタイプ(句9)の場合、Tのデフォルトコンストラクターが呼び出されます(Tにアクセス可能なデフォルトコンストラクターがない場合、初期化の形式が正しくありません);
— Tが配列型の場合、各要素はデフォルトで初期化されます。
それ以外の場合、オブジェクトはゼロで初期化されます。T型のオブジェクトを値初期化するとは、次のことを意味します
。Tがユーザー宣言のコンストラクター(12.1)を持つクラス型(9節)の場合、Tのデフォルトコンストラクターが呼び出されます(Tの場合、初期化は正しくありませんアクセス可能なデフォルトコンストラクターがない);
— Tがユーザー宣言コンストラクタのない非共用クラス型である場合、Tのすべての非静的データメンバーおよび基本クラスコンポーネントは値で初期化されます。
— Tが配列型の場合、各要素は値で初期化されます。
それ以外の場合、オブジェクトはゼロで初期化されます参照型のエンティティのデフォルトの初期化または値の初期化を要求するプログラムは、形式が正しくありません。Tがcv修飾型の場合、ゼロ初期化、デフォルト初期化、および値初期化のこれらの定義には、Tのcv非修飾バージョンが使用されます。