web-dev-qa-db-ja.com

C ++では、ゼロ、デフォルト、値の初期化というフレーズはどういう意味ですか?

C++で次のフレーズは何を意味しますか?

  • ゼロ初期化、

  • デフォルトの初期化、および

  • 値の初期化

C++開発者はそれらについて何を知るべきですか?

178
Bill

理解すべきことの1つは、「値の初期化」がC++ 2003標準で新しく追加されたことです。元の1998標準には存在しません(明確化以上の違いがあると思います)。標準から直接の定義については、 Kirill V. Lyadvinsky's answer を参照してください。

これらのタイプの初期化のさまざまな動作の詳細、およびそれらが開始されるとき(およびc ++ 98とC++ 03で異なる場合)の詳細については、operator newの動作に関するこの前の回答を参照してください。

答えの要点は次のとおりです。

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;
}
61
Michael Burr

C++ 03標準8.5/5:

zero-initializeタイプTのオブジェクトの意味:
— Tがスカラー型(3.9)の場合、オブジェクトはTに変換された0(ゼロ)の値に設定されます。
— Tが非ユニオンクラスタイプの場合、各非静的データメンバーと各ベースクラスサブオブジェクトはゼロで初期化されます。
— Tがユニオン型の場合、オブジェクトの最初の名前付きデータメンバーはゼロで初期化されます。
— Tが配列型の場合、各要素はゼロで初期化されます。
— Tが参照タイプの場合、初期化は実行されません。

default-initializeタイプTのオブジェクトの意味:

— Tが配列型の場合、各要素はデフォルトで初期化されます。
—それ以外の場合、オブジェクトはゼロで初期化されます。

To value-initializeタイプTのオブジェクトは以下を意味します:
[。 ;
— Tが、ユーザーが宣言したコンストラクターを持たない非共用クラス型である場合、Tのすべての非静的データメンバーと基本クラスコンポーネントは値で初期化されます。
— Tが配列型の場合、各要素は値で初期化されます。
—それ以外の場合、オブジェクトはゼロで初期化されます

参照型のエンティティのデフォルト初期化または値初期化を呼び出すプログラムは、形式が正しくありません。 Tがcv修飾型である場合、ゼロ初期化、デフォルト初期化、および値初期化のこれらの定義には、Tのcv非修飾バージョンが使用されます。

84