以下短语在 C++ 中是什么意思:零初始化、默认初始化和值初始化?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1613341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:37:26  来源:igfitidea点击:

What do the following phrases mean in C++: zero-, default- and value-initialization?

c++initializationc++-faq

提问by Bill

What do the following phrases mean in C++:

以下短语在 C++ 中的含义是什么:

  • zero-initialization,

  • default-initialization, and

  • value-initialization

  • 零初始化,

  • 默认初始化,和

  • 值初始化

What should a C++ developer know about them?

C++ 开发人员应该对它们了解什么?

采纳答案by Michael Burr

One thing to realize is that 'value-initialization' is new with the C++ 2003 standard - it doesn't exist in the original 1998 standard (I think it might be the only difference that's more than a clarification). See Kirill V. Lyadvinsky's answerfor the definitions straight from the standard.

需要意识到的一件事是“值初始化”是 C++ 2003 标准的新内容——它在 1998 年的原始标准中不存在(我认为这可能是唯一的区别,不仅仅是澄清)。请参阅Kirill V. Lyadvinsky对直接来自标准的定义的回答

See this previous answer about the behavior of operator newfor details on the the different behavior of these type of initialization and when they kick in (and when they differ from c++98 to C++03):

有关operator new这些类型的初始化的不同行为以及它们何时启动(以及它们何时从 c++98 到 C++03 不同)的详细信息,请参阅有关行为的先前答案:

The main point of the answer is:

答案的主要观点是:

Sometimes the memory returned by the new operator will be initialized, and sometimes it won't depending on whether the type you're newing up is a POD, or if it's a class that contains POD members and is using a compiler-generated default constructor.

  • In C++1998 there are 2 types of initialization: zero and default
  • In C++2003 a 3rd type of initialization, value initialization was added.

有时 new 操作符返回的内存会被初始化,有时它不会取决于你新建的类型是 POD,还是包含 POD 成员的类并使用编译器生成的默认构造函数.

  • 在 C++1998 中有两种类型的初始化:零和默认
  • 在 C++2003 中,添加了第三种类型的初始化,即值初始化。

To say they least, it's rather complex and when the different methods kick in are subtle.

至少可以说,它相当复杂,而且不同的方法开始时很微妙。

One thing to certainly be aware of is that MSVC follows the C++98 rules, even in VS 2008 (VC 9 or cl.exe version 15.x).

需要注意的一件事是 MSVC 遵循 C++98 规则,即使在 VS 2008(VC 9 或 cl.exe 版本 15.x)中也是如此。

The following snippet shows that MSVC and Digital Mars follow C++98 rules, while GCC 3.4.5 and Comeau follow the C++03 rules:

以下代码段显示 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;
}

回答by Kirill V. Lyadvinsky

C++03 Standard 8.5/5:

C++03 标准 8.5/5:

To zero-initializean object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the object's first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.

To default-initializean object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the object is zero-initialized.

To value-initializean object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized

A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed. If T is a cv-qualified type, the cv-unqualified version of T is used for these definitions of zero-initialization, default-initialization, and value-initialization.

对T 类型的对象进行零初始化意味着:
— 如果 T 是标量类型 (3.9),则将该对象设置为转换为 T 的 0(零)值;
— 如果 T 是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;
— 如果 T 是联合类型,则对象的第一个命名数据成员为零初始化;
— 如果 T 是数组类型,则每个元素都初始化为零;
— 如果 T 是引用类型,则不执行初始化。

默认初始化的类型T的装置的对象:
-如果T是一个非POD类型(第9节),T的默认构造函数被调用(并形成不良的初始化如果T没有可访问的缺省的构造);
— 如果 T 是数组类型,则每个元素都是默认初始化的;
— 否则,对象是零初始化的。

值初始化的类型T的装置的对象:
-如果T是一个类型(第9节)与用户声明的构造(12.1),然后对T中的默认构造函数被调用(以及初始化是形成不良的如果T没有可访问的默认构造函数);
— 如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件都进行了值初始化;
— 如果 T 是数组类型,则每个元素都进行了值初始化;
— 否则,对象是零初始化的

调用引用类型实体的默认初始化或值初始化的程序是格式错误的。如果 T 是 cv 限定类型,则 T 的 cv 非限定版本用于零初始化、默认初始化和值初始化的这些定义。