C ++では、ゼロ、デフォルト、値の初期化というフレーズは何を意味しますか?
-
06-07-2019 - |
質問
C ++での次のフレーズの意味:
-
ゼロ初期化、
-
default-initialization、および
-
値の初期化
C ++開発者はそれらについて何を知るべきですか?
解決
実現すべきことの1つは、「値の初期化」がC ++ 2003標準で新しくなったことです。元の1998標準には存在しません(明確化以上の違いがあると思います)。 Kirillをご覧ください。 V.リャドビンスキーの回答は、標準から直接定義されています。
これらのタイプの初期化のさまざまな動作の詳細と、それらが開始されるタイミング(およびc ++ 98からC +と異なる場合)の詳細については、 operator new
の動作に関するこの前の回答を参照してください+03):
答えの要点は次のとおりです。
new演算子によって返されるメモリは初期化されることがあります。また、新しいタイプがPODであるかどうか、またはPODメンバーを含みコンパイラを使用するクラスであるかどうかに依存しない場合があります。生成されたデフォルトのコンストラクタ。
- C ++ 1998には、ゼロとデフォルトの2種類の初期化があります
- C ++ 2003の3番目のタイプの初期化では、値の初期化が追加されました。
控えめに言っても、それはかなり複雑であり、異なる方法が起動するときは微妙です。
確かに注意すべきことの1つは、VS 2008(VC 9またはcl.exeバージョン15.x)であっても、MSVCはC ++ 98の規則に従うということです。
次のスニペットは、MSVCとDigital MarsがC ++ 98の規則に従っているのに対し、GCC 3.4.5とComeauはC ++ 03の規則に従っていることを示しています。
#include <stdio.h>
#include <string.h>
#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)];
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
printf( "m is %d\n", pB->m);
return 0;
}
他のヒント
C ++ 03標準8.5 / 5:
ゼロ初期化 とは、タイプTのオブジェクトを意味します:
&#8212; Tがスカラー型(3.9)の場合、オブジェクトはTに変換された値0(ゼロ)に設定されます;
&#8212; Tが非ユニオンクラス型の場合、各非静的データメンバーと各ベースクラスサブオブジェクトはゼロで初期化されます;
&#8212; Tがユニオン型の場合、オブジェクトの最初の名前付きデータメンバーはゼロで初期化されます;
&#8212; Tが配列型の場合、各要素はゼロで初期化されます;
&#8212; Tが参照型の場合、初期化は実行されません。default-initialize とは、タイプTのオブジェクトを意味します:
&#8212; Tが非PODクラス型(9節)の場合、Tのデフォルトコンストラクターが呼び出されます(Tにアクセス可能なデフォルトコンストラクターがない場合、初期化は不正な形式です);
&#8212; Tが配列型の場合、各要素はデフォルトで初期化されます;
&#8212;それ以外の場合、オブジェクトはゼロで初期化されます。value-initialize とは、タイプTのオブジェクトを意味します:
&#8212; Tがユーザー宣言コンストラクタ(12.1)を持つクラス型(9節)である場合、Tのデフォルトコンストラクタが呼び出されます(Tにアクセス可能なデフォルトコンストラクタがない場合、初期化は不正な形式です);
&#8212; Tがユーザー宣言コンストラクターを持たない非共用クラス型である場合、Tのすべての非静的データメンバーと基本クラスコンポーネントは値で初期化されます;
&#8212; Tが配列型の場合、各要素は値で初期化されます;
&#8212;それ以外の場合、オブジェクトはゼロで初期化されます参照型のエンティティのdefault-initializationまたはvalue-initializationを呼び出すプログラムは不正な形式です。 Tがcv修飾型である場合、ゼロ初期化、デフォルト初期化、および値初期化のこれらの定義には、Tのcv非修飾バージョンが使用されます。