[英]Why is a POD in a struct zero-initialized by an implicit constructor when creating an object in the heap or a temporary object in the stack?
标准和 C ++的书说,对于类类型成员的默认构造函数被隐式生成默认构造函数调用,但内建类型不被初始化。 但是,在此测试程序中,在堆中分配对象或使用临时对象时会出现意外结果:
#include<iostream>
struct Container
{
int n;
};
int main()
{
Container c;
std::cout << "[STACK] Num: " << c.n << std::endl;
Container *pc = new Container();
std::cout << "[HEAP] Num: " << pc->n << std::endl;
delete pc;
Container tc = Container();
std::cout << "[TEMP] Num: " << tc.n << std::endl;
}
我得到这个输出:
[STACK] Num: -1079504552
[HEAP] Num: 0
[TEMP] Num: 0
这是一些编译器特定的行为吗? 我真的不打算依赖它,但我很想知道为什么会这样,特别是第三种情况。
这是预期的行为。 有两个概念,“默认初始化”和“值初始化”。 如果你没有提到任何初始化器,那么对象是“默认初始化”,而如果你确实提到它,即使是默认构造函数的(),对象也是“值初始化”。 定义构造函数时,两种情况都会调用默认构造函数。 但对于内置类型,“值初始化”将内存归零,而“默认初始化”则不归零。
所以当你初始化时:
Type x;
如果提供了默认构造函数,它将调用默认构造函数,但原始类型将是未初始化的。 但是当你提到初始化器时,例如
Type x = {}; // only works for struct/class without constructor
Type x = Type();
Type x{}; // C++11 only
原始类型(或结构的原始成员)将被VALUE初始化。
同样地:
struct X { int x; X(); };
如果你定义构造函数
X::X() {}
x成员将是未初始化的,但如果您定义构造函数
X::X() : x() {}
它将被VALUE初始化。 这也适用于new
,所以
new int;
应该给你未初始化的记忆,但是
new int();
应该给你的内存初始化为零。 不幸的是语法:
Type x();
由于语法歧义而不允许
Type x = Type();
如果它们都是指定的且不可内联的,则必须调用默认构造函数, 后跟复制构造函数。
C ++ 11引入了新的语法,
Type x{};
这两种情况都可以使用。 如果您仍然坚持使用较旧的标准,那就是Boost.ValueInitialized的原因,因此您可以正确初始化模板参数的实例。
可以在Boost.ValueInitialized文档中找到更详细的讨论。
简短的回答是:空括号执行值初始化 。
当你说Container *pc = new Container;
相反,你会观察到不同的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.