隐式声明的默认构造函数具体形式是什么?
C++中隐式构造、默认构造函数与自定义空构造函数的初始化差异
这确实是C++标准明确规定的行为,属于很容易混淆的细节点!咱们来逐个拆解你遇到的三种场景:
1. 无用户声明构造函数的隐式构造
struct Foo { int member; };
当你声明const Foo implicit_construction;时,触发的是默认初始化。由于这个结构体没有任何用户声明的构造函数,编译器会生成一个平凡默认构造函数——这类构造函数的特点是完全不干预非静态成员的初始化,所以member会保留内存里的随机垃圾值,处于未定义状态。
2. 显式默认的构造函数
struct Foo { Foo() = default; int member; };
显式使用= default声明的构造函数,只要满足平凡构造函数的条件(这里显然满足,因为没有自定义逻辑),它的行为就和编译器隐式生成的平凡构造函数完全一致。所以const Foo defaulted_construction;依然是默认初始化,member还是未初始化的状态。
3. 自定义空构造函数
struct Foo { Foo(){}; int member; };
这里的关键变化来了:哪怕构造函数是空的,只要是用户显式定义的,它就不再是平凡构造函数。当你声明const Foo defined_construction;时,因为对象是const类型且存在用户定义的构造函数,此时会触发值初始化——值初始化规则要求对非类类型的成员执行零初始化,所以member被自动设置为0。
为什么你会误以为二者等价?
很多开发者会直觉上认为= default和空的自定义构造函数是一回事,但C++标准对这两种情况的初始化规则做了明确区分:
- 平凡默认构造函数(隐式生成或显式
= default且符合条件):默认初始化时不会处理内置类型成员 - 用户定义的构造函数(哪怕没有任何逻辑):对于
const对象的初始化会触发值初始化,进而对内置类型成员执行零初始化
简单来说,核心差异在于构造函数是否属于“用户定义”,以及对应的初始化规则是默认初始化还是值初始化。
内容的提问来源于stack exchange,提问作者Jonathan Mee
相关产品推荐
相关产品推荐

