0

我读了一本书 S. Lippman "inside c++ object model",有没有这样的代码

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 对象是在堆上创建的,根据上面所说,这个对象不是全局的,它不会被称为默认构造函数。我理解正确吗?

4

3 回答 3

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.
于 2013-11-07T08:27:05.970 回答
1

The parentheses in new Foo() specify value initialisation; this basically means that each member is zero-initialised. If instead you said new Foo, then the members would be left uninitialised, as they are for your automatic variable.

Unfortunately, to value-initialise the automatic variable, you can't write Foo bar(), since that declares a function. You'll need

Foo bar{};        // C++11
Foo bar = Foo();  // Historical C++
于 2013-11-07T08:31:34.000 回答
0

如果一个类没有默认构造函数(也没有其他构造函数),编译器会为你创建一个。它必须这样做,否则您将无法创建该类的实例。但是,生成的默认构造函数不会做任何事情。

添加空括号集的new Foo()作用是对分配的对象进行值初始化,这意味着成员被初始化为其“默认”值,对于整数和浮点值以及nullptr指针,该值为零。

于 2013-11-07T08:25:07.740 回答