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