下面这些短语在c++中是什么意思:0 -,default-和value-initialization?

下面这些短语在c++中是什么意思:

  • zero-initialization,

  • default-initialization,

  • value-initialization

c++开发人员应该了解哪些?

35571 次浏览

c++ 03标准8.5/5:

对于< em > zero-initialize < / em >,类型为T的对象意味着:
—如果T是一个标量类型(3.9),对象被设置为0(零)转换为T的值;
-如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的 -如果T是联合类型,对象的第一个命名数据成员是零初始化的 —如果T是数组类型,则每个元素初始化为0;
—如果T是引用类型,则不进行初始化。< / p > 对于< em > default-initialize < / em >,类型为T的对象意味着:
-如果T是非pod类类型(子句9),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化为病态形式) —如果T是数组类型,则每个元素默认初始化 -否则,对象为零初始化。< / p > 对于< em > value-initialize < / em >,类型为T的对象意味着:
-如果T是一个类类型(第9条),具有用户声明的构造函数(12.1),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化为病态形式) -如果T是一个没有用户声明构造函数的非联合类类型,那么T的每个非静态数据成员和基类组件都是值初始化的 -如果T是数组类型,则每个元素都是值初始化的 -否则,对象为零初始化

调用引用类型实体的默认初始化或值初始化的程序是病态形式的。如果T是一个cv-qualified类型,则T的cv-qualified版本用于这些零初始化、默认初始化和值初始化的定义。

需要意识到的一件事是,“值初始化”在c++ 2003标准中是新的——它在最初的1998标准中不存在(我认为这可能是唯一的区别,不仅仅是澄清)。参见Kirill V. Lyadvinsky的回答直接从标准中获得定义。

有关这些类型的初始化的不同行为以及它们何时开始生效(以及它们从c++98到c++ 03的不同之处)的详细信息,请参阅前面关于operator new行为的回答:

答案的要点是:

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

  • 在c++ 1998中,有两种初始化类型:0和default
  • 在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;
}