在堆上创建的对象不是全局的?

时间:2013-11-07 08:21:59

标签: c++ memory default-constructor global-object

我读了一本书S. Lippman“里面的c ++对象模型”,有没有这样的代码

class Foo { public: int val; Foo *pnext; };
void foo_bar()
{
// Oops: program needs bar's members zeroed out
Foo bar;
Foo* baz = new Foo(); // this line i added myself
if ( bar.val || bar.pnext )
// ... do something
// ...
}

它说 “此代码片段未合成默认构造函数。

保证全局对象在程序启动时将其关联的内存“清零”。本地对象 在程序堆栈上分配并在免费存储上分配的堆对象没有相关的内存 归零;相反,内存保留了之前使用的任意位模式。“

在这段代码中,baz对象是在堆上创建的,根据上面所说的,这个对象不是全局的,也不会被称为默认构造函数。我理解正确吗?

3 个答案:

答案 0 :(得分:1)

执行此操作时:

Foo* baz = new Foo();

您正在动态分配Foo个实例并值初始化它。对于POD,这意味着成员零初始化。如果你说过这个(假设非全局背景):

Foo* baz = new Foo;

然后Foo实例将被默认初始化,这意味着不会执行其成员的初始化,因为它们是POD。

这也适用于自动存储实例:

Foo f0; // default initializaiton: members not zeroed out.
Foo f1 = Foo(); // value initialization: members zeroed out.
Foo f2{}; // C++11 value initialization: members zeroed out.
Foo f3(); // Ooops! Function declaration. Something completely different.

答案 1 :(得分:1)

new Foo()中的括号指定值初始化;这基本上意味着每个成员都是零初始化的。如果您说new Foo,那么成员将保持未初始化状态,因为它们适用于您的自动变量。

不幸的是,要对自动变量进行值初始化,您不能编写Foo bar(),因为它声明了一个函数。你需要

Foo bar{};        // C++11
Foo bar = Foo();  // Historical C++

答案 2 :(得分:0)

如果一个类没有默认构造函数(并且没有其他构造函数),编译器将为您创建一个。它必须,或者您将无法创建该类的实例。但是,生成的默认构造函数不会执行任何操作。

new Foo()中添加空括号的方法是什么,值是初始化已分配的对象,这意味着成员被初始化为其“默认”值,对于整数和浮点值为零,并且nullptr指示。