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用于零初始化,默认初始化和值初始化的这些定义.
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)