C++无括号与空括号初始化的区别及用户定义构造函数的影响
C++ 中
Foo foo;与Foo foo{};初始化方式的区别 核心规则差异
首先明确两种写法对应的初始化类型:
Foo foo;属于默认初始化Foo foo{};属于C++11引入的列表初始化(空初始化列表场景),触发值初始化逻辑
两者的行为差异完全取决于类是否存在用户定义的无参构造函数:
场景1:类存在用户定义的无参构造函数
不管是默认初始化还是空列表初始化,都会调用自定义的无参构造函数。
如果构造函数没有在初始化列表中显式初始化int、数组这类内置类型成员,那么这些成员不会被自动赋值,值是未定义的随机垃圾值,也就是你测试中foo1、foo2输出都是乱数的原因。
场景2:类没有用户定义的无参构造函数
- 默认初始化(
Foo foo;):内置类型成员不会被初始化,值为随机垃圾值,对应你测试中bar1的输出 - 空列表初始化(
Foo foo{};):触发零初始化,所有内置类型成员都会被赋值为0,对应你测试中bar2的全0输出
测试结果对应解释
你给出的四行输出正好匹配四个初始化场景的运行结果:
- 第一行:
Foo foo1默认初始化,自定义无参构造未初始化数组成员,输出随机值 - 第二行:
Foo foo2{}列表初始化,仍调用自定义无参构造,未初始化数组,输出随机值 - 第三行:
Bar bar1默认初始化,无自定义构造,内置数组未初始化,输出随机值 - 第四行:
Bar bar2{}列表初始化,触发零初始化,数组全为0
补充说明
如果无参构造写为Foo() = default;,这属于用户声明但非用户提供的构造函数,不属于"用户定义构造函数"的范畴,此时Foo foo{};仍然会触发零初始化。
内容的提问来源于stack exchange,提问作者Leon Cruz
相关产品推荐
相关产品推荐

