显式默认默认构造函数的类成员会被零初始化吗?
显式默认默认构造函数能保证成员零初始化吗?
好问题!这确实是C++初始化规则里很容易踩坑的细节,咱们把这个问题拆解开来说清楚:
先回顾基础场景
首先看你提到的第一个例子:
class MyClass { public: int value; }; MyClass c; std::cout << c.value; // 未定义行为:value未初始化
这里因为类没有声明任何构造函数,创建c时执行的是默认初始化。对于内置类型(比如int)来说,默认初始化就是不做任何初始化操作,所以value的值是随机的,访问它属于未定义行为,这部分你已经理解了。
显式默认构造函数的情况
那当我们显式默认默认构造函数时:
class MyClass { public: int value; MyClass() = default; }; MyClass c; std::cout << c.value; // 依然是未定义行为!
为什么?核心原因在于:显式默认的构造函数如果是trivial(平凡)的,默认初始化的规则和没有声明构造函数时完全一致。
这里的MyClass() = default;是一个平凡默认构造函数——因为它没有任何用户自定义的初始化逻辑,且所有成员都是内置类型。当用MyClass c;这种方式默认初始化对象时,平凡默认构造函数不会对内置类型成员做任何初始化,value依然是未初始化的随机值,访问它还是未定义行为,无法保证输出0。
什么时候能得到零初始化?
要让value被零初始化,你需要触发值初始化而非默认初始化,常见的场景有:
- 使用列表初始化:
MyClass c{}; - 使用带括号的new表达式:
MyClass* p = new MyClass();
值初始化的规则是:如果对象的默认构造函数是平凡的,就直接对整个对象做零初始化;如果是非平凡的,就先零初始化再调用构造函数。这两种情况下,value都会被设置为0。
另外,还有两种更直接的方式保证value被初始化:
- 类内初始化成员:
int value = 0;,这样不管是默认初始化还是值初始化,value都会被初始化为0。 - 自定义构造函数显式初始化:
MyClass() : value(0) {},替代= default;,强制在构造时初始化value。
总结一下核心结论
- 仅显式默认默认构造函数,并用
MyClass c;这种默认初始化方式创建对象时,无法保证内置类型成员被零初始化,访问未初始化成员依然是未定义行为。 - 要实现零初始化,要么改用值初始化的语法,要么显式初始化成员(类内初始化或构造函数初始化列表)。
内容的提问来源于stack exchange,提问作者Alecto
相关产品推荐
相关产品推荐

