以下短语在C ++中是什么意思:
零初始化
默认初始化,以及
价值初始化
C ++开发人员应该了解什么?
以下短语在C ++中是什么意思:
零初始化
默认初始化,以及
价值初始化
C ++开发人员应该了解什么?
Answers:
要意识到的一件事是,“值初始化”是C ++ 2003标准的新增功能-最初的1998标准中不存在(我认为这可能是唯一的区别,而不仅仅是澄清)。有关标准的直接定义,请参见Kirill V. Lyadvinsky的答案。
有关operator new
这些类型的初始化的不同行为及其启动的时间(以及从c ++ 98到C ++ 03的不同时间),请参见有关的行为的先前答复,以获取详细信息:
答案的重点是:
有时,new运算符返回的内存将被初始化,有时它并不取决于您要更新的类型是POD,还是它是包含POD成员并且正在使用编译器生成的默认构造函数的类。
- 在C ++ 1998中,有两种初始化类型:零和默认
- 在C ++ 2003的第三种初始化类型中,添加了值初始化。
至少可以说,这很复杂,并且在采用不同的方法时很微妙。
要知道的一件事是,即使在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;
}
int
,但是m()
在第三行,值初始化m。如果更改int m;
为,则很重要B m;
。:)
A
而C
在这个例子中,不使用(他们是从其他链接的答案结转)。即使C ++ 98和C ++ 03在描述A
和C
构造时使用了不同的术语,但两个标准的结果是相同的。仅struct B
导致不同的行为。
struct C { C() : m() {}; ~C(); B m; };
,则您将为m.m
0。但是,如果m
像您说的C ++ 03那样进行默认初始化,则m.m
不会像在C ++ 98中那样进行初始化。
C ++ 03标准8.5 / 5:
对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非限定版本用于零初始化,默认初始化和值初始化的这些定义。