=default仅适用于类内声明的六个特殊成员函数,不能用于普通函数或变量;若类含const/引用成员或已有用户构造函数,则类内=default可能失败,需类外定义或确保成员可默认初始化。

default只能用在特殊成员函数声明里
它不是初始化语法,也不是通用默认值开关,只允许出现在类内声明的六个特殊成员函数之后:MyClass()、~MyClass()、MyClass(const MyClass&)、MyClass(MyClass&&)、operator=(const MyClass&)、operator=(MyClass&&)。写在普通函数或变量初始化处(比如 int x = default;)会直接报错:error: 'default' cannot be used outside of a function declaration。
类内声明= default不总能生效
看似写了 MyClass() = default; 就万事大吉,但实际是否真能生成,默认构造函数还受制于类的其他定义:
- 如果类里有
const成员或引用成员,编译器不会合成默认构造函数 —— 因为它们必须在初始化列表中显式绑定;此时类内写= default会触发编译错误:field 'ref' must be initialized - 如果类已有用户定义的构造函数(哪怕只有一个带参构造),编译器就不再隐式合成默认构造;这时
= default是唯一恢复它的办法,但前提是所有成员支持默认初始化(或已提供类内默认成员初始化器,如int x = 0;) - 若想绕过限制,得把
= default搬到类外定义:比如声明为MyClass();,再在 .cpp 里写MyClass::MyClass() = default;,并确保初始化列表可推导(或手动补全)
为什么不能只删掉声明而依赖编译器自动生成
一旦你显式写了任何特殊成员函数(哪怕只是空的析构函数 ~MyClass() {}),编译器就会“收手”——它不再为你合成移动构造和移动赋值。这时候,= default 是唯一能重新启用移动语义的方式:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
~MyClass() { cleanup(); }→ 编译器不生成移动操作 -
MyClass(MyClass&&) = default;→ 显式恢复移动构造,且保持noexcept属性(手动写空函数则不自动具备) - 同理,
= delete和= default可共存于同一类,但顺序很重要:= delete必须写在= default之前,否则可能触发语法错误
移动操作的生成条件比你想的更苛刻
编译器不会因为你没写移动函数就自动给你补上。它只在极窄条件下合成默认移动构造/赋值:
立即学习“C++免费学习笔记(深入)”;
- 你没自己写移动构造 且 没写析构函数 且 没写拷贝构造 且 没写拷贝赋值 —— 四者全无,才可能合成
- 只要其中任一被显式定义(哪怕是
= default或= delete),这个条件就破了,移动操作就不会自动生成 - 所以,哪怕你只想禁用拷贝、保留移动,也必须显式写
MyClass(const MyClass&) = delete;和MyClass(MyClass&&) = default;,缺一不可

















