默认构造函数 C++
Posted
技术标签:
【中文标题】默认构造函数 C++【英文标题】:Default constructors C++ 【发布时间】:2011-05-09 20:48:48 【问题描述】:假设我有这门课:
class X
public:
int x;
;
我看到如果我在本地创建一个 X 的实例,x 不会被初始化为 0,只有当我全局创建它时。 这是否意味着编译器不会为本地创建的对象合成默认构造函数(我对此表示怀疑),或者它将被合成但不会将 x 值归零,如果是这种情况,为什么会这样?
【问题讨论】:
int
从来没有默认构造函数,它是一个原语。有时它对您来说是 0 的事实是侥幸,而不是任何标准所要求的。总是总是初始化你的变量。
@Chris:这不是侥幸。具有静态存储持续时间的对象(包括大多数全局变量)在任何其他初始化发生之前被初始化为零。这意味着全局 int 值从 0 开始。
您没有得到有用或正确答案的原因是因为实际答案需要好几页一本好的 C++ 教科书——您正在阅读哪一本?
答案部分取决于您如何“在本地创建 X 的实例”。你说X x;
、X x = X();
、X*p = new X;
还是X *p = new X();
?
@Dennis Zickefoose:很有趣。现在我知道了,并且知道 > 0.5 * 战斗。
【参考方案1】:
C++ 中的构造函数通常不会将成员初始化为 0。您必须使用值显式初始化成员。
在全局情况下内存为零的原因是因为静态内存在其他任何事情发生之前就被初始化为零。在您的情况下,隐式生成的默认构造函数随后被调用,它不会触及成员 X 的内存。
另请参阅 Derek 的回答:Is global memory initialized in C++?
但是请注意,结构化的非 POD 成员(类和结构)的默认构造函数会自动被默认构造函数调用。默认情况下,只有 POD 成员处于单独状态。
【讨论】:
但是如果全局创建X的实例,它会通过编译器合成的默认构造函数将x初始化为0 这也是错误的。现实更加复杂。但重要的是,全局内存没有“归零”,构造函数确实在非 POD 上被调用。 @TheFogger 我只能重复一遍:对于非 POD,根本不是这种情况。非 POD 的全局对象不会被清零,它们的默认构造函数会被调用。自己看:gist.github.com/963414 @TheFogger 非 POD 静态变量初始化为零,然后调用构造函数。 我想我明白我们的误解在哪里了。内存确实被清零,但默认构造函数随后被调用。如果您不指定默认构造函数,则隐式生成的构造函数不会对 POD 成员执行任何操作。因此,它们将保持为零。【参考方案2】:X
得到一个合成构造函数,但合成构造函数不对原语进行零初始化。
【讨论】:
【参考方案3】:您将对象构造的概念与成员初始化相结合。作为一般规则,不要指望 C++ 为您初始化原始数据成员,您需要自己做(最好通过构造函数后的初始化列表。)
这主要是为了速度,因为这允许在没有初始化的情况下进行分配,例如,如果您稍后将计算数据成员的值并覆盖任何“默认”值,这很有用。
我在过去发现此站点是一个有用的参考:http://www.cplusplus.com/doc/tutorial/variables/
【讨论】:
“C++ 不会自动为你初始化数据成员”——是的,在某些情况下会这样做。 已编辑以限定声明【参考方案4】:默认构造函数不知道它应该初始化你的成员变量。如果您需要将 x 初始化为某些东西,您最好添加自己的构造函数来为您执行此操作:
class X
public:
X() : x(0) ;
int x;
;
【讨论】:
但是如果我的对象是在任何函数(全局)之外创建的,为什么它知道我的成员 x ?因为它会将其初始化为 0 编译器合成的默认构造函数肯定“知道”您的成员变量。是否初始化它们是另一个问题。 我的意思是编译器不知道默认构造函数应该初始化私有成员变量。我不是以英语为母语的人,让这位兄弟休息一下。 ;D 已修复,感谢指出。尽可能删除反对票,谢谢。 这与私有成员变量无关。如果可以的话,合成的构造函数肯定会初始化私有成员变量(通过它们的构造函数)。这整个领域比你想象的要复杂得多 - 因此投反对票。 “它应该初始化你的成员变量”是主观的。默认构造函数并非不知道该场景;简单地说,语言选择不这样做。以上是关于默认构造函数 C++的主要内容,如果未能解决你的问题,请参考以下文章