繁体   English   中英

为什么在堆中创建对象或堆栈中的临时对象时,隐式构造函数对结构中的POD进行零初始化?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM