以下短语在C++中的含义是什么:零,默认和值初始化?

Bil*_*ill 183 c++ initialization c++-faq

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

  • 零初始化,

  • 默认初始化,和

  • 值初始化

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

Kir*_*sky 86

C++ 03标准8.5/5:

零初始化类型T的对象是指:
-如果T是一个标量类型(3.9),所述对象被设置为0(零)的值转换至T;
- 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;
- 如果T是联合类型,则对象的第一个命名数据成员为零初始化;
- 如果T是数组类型,则每个元素都是零初始化的;
- 如果T是引用类型,则不执行初始化.

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

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

调用引用类型实体的默认初始化或值初始化的程序是不正确的.如果T是cv限定类型,则cv非限定版本的T用于零初始化,默认初始化和值初始化的这些定义.

  • 对于C++ 11,这可能已经过时了.[cppreference.com](http://en.cppreference.com/w/cpp/language/default_initialization)声明默认初始化_does not_ zero-initialize members(只有值初始化确实). (17认同)
  • @android提出了一个重点,我在其他地方看不到答案,所以我提出了一个新问题.http://stackoverflow.com/questions/22233148/meaning-of-default-initialization-changed-in-c11 (3认同)

Mic*_*urr 64

有一点需要注意的是,"值初始化"是C++ 2003标准的新特性 - 它在1998年的原始标准中并不存在(我认为它可能是唯一的区别,不仅仅是澄清).请参阅Kirill V. Lyadvinsky对标准定义的回答.

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

答案的要点是:

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

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

至少可以说,它是相当复杂的,当不同的方法开始是微妙的.

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

下面的代码片段显示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;
}
Run Code Online (Sandbox Code Playgroud)

  • 并不是说它对 `int` 很重要,但是第三行值上的 `m()` 初始化了 m。如果您将 `int m;` 更改为 `B m;`,则很重要。:) (2认同)