C++中=default声明的构造函数与编译器生成的构造函数有何区别?
两种默认构造函数的核心区别
两种构造函数的实际执行逻辑基本一致,都会按照C++标准规则初始化类的非静态成员,本身不会添加额外的执行逻辑,但存在以下几处关键的语法层面差异:
- 聚合类型资格不同
代码2的Dog类如果将成员x改为public权限,满足聚合类型要求,可以用Dog d{123}的聚合初始化语法直接给成员赋值;而代码1因为显式声明了构造函数,哪怕是=default版本,也不再属于聚合类型,无法使用聚合初始化语法。 - 属性与访问权限可控性不同
显式用=default声明的默认构造函数可以自由指定访问权限,也可以添加constexpr、noexcept等修饰符,比如可以将其放在private区段实现禁止外部默认构造类实例的需求;而编译器隐式生成的默认构造函数固定为public权限,是否带有constexpr、noexcept属性完全由编译器根据标准规则判定,开发者无法手动调整。 - 存在性规则不同
编译器隐式生成默认构造的前提是类没有任何用户声明的其他构造函数,如果你后续给类新增了带参构造函数,隐式默认构造会自动失效;而显式=default声明的默认构造不受该规则影响,哪怕后续新增其他构造函数,默认构造依然可以正常调用。
如果将=default的实现放在类外(类内仅声明Dog();,类外实现Dog::Dog()=default;),此时生成的默认构造不属于平凡构造函数,而隐式生成的默认构造只要满足条件就属于平凡构造。 - 实例化时机不同
隐式生成的默认构造只有在代码实际调用默认构造逻辑时才会被编译器实例化;而显式=default的默认构造只要完成声明,无论是否被调用都会被编译器实例化。
内容的提问来源于stack exchange,提问作者Noya_G
相关产品推荐
相关产品推荐

