在 C++11 中,= default 和 = delete 是两个让程序员显式控制编译器自动生成代码的能力。它们主要用于特殊成员函数(默认构造、析构、拷贝/移动构造、拷贝/移动赋值),但 = delete 还可以用在普通函数上。
简单类比:
-
= default:告诉编译器 “请显式生成这个函数的默认版本”。 -
= delete:告诉编译器 “禁止使用这个函数,谁调用了谁编译报错”。
1. = default(显式默认)
使用场景:当你自定义了带参构造函数后,编译器不会再自动生成无参默认构造函数。如果你依然需要无参构造,可以用 = default 强制生成。此外,它能让编译器生成的版本保持最高效率(如 trivial 特性),比手写空构造更好。
cpp
class A {
public:
A(int x) : data(x) {} // 自定义构造函数
A() = default; // ★ 强制恢复默认无参构造,即便上面定义了其他构造
private:
int data;
};
2. = delete(显式删除)
使用场景:
-
禁止拷贝(实现单例或独占资源类)。
-
禁止隐式类型转换(重载函数时,删除特定类型的参数)。
-
在 C++98 中,我们曾将拷贝构造设为
private且不实现,现在用= delete更优雅,且编译报错信息更清晰。
#include <iostream>
class Resource {
public:
int value;
// 1. 自定义带参构造
Resource(int v) : value(v) {
std::cout << "Resource(int) constructed" << std::endl;
}
// 2. = default:强行保留默认无参构造(即使上面定义了带参构造)
Resource() = default;
// 3. = delete:禁止拷贝构造(让对象不可拷贝)
Resource(const Resource&) = delete;
// 4. = delete:禁止拷贝赋值运算符
Resource& operator=(const Resource&) = delete;
// 5. = default:显式要求编译器生成默认析构(通常用于保持 trivial 性)
~Resource() = default;
// ★ 额外:= delete 也能用于普通函数,用于拦截特定的隐式转换
void setValue(double d) = delete; // 禁止用 double 赋值
void setValue(int i) {
value = i;
std::cout << "setValue(int) called" << std::endl;
}
};
int main() {
// ----- 验证 = default -----
Resource r1(10); // 调用自定义构造
Resource r2; // 调用被 =default 恢复的无参构造(编译成功)
r2.value = 20;
std::cout << "r1 value: " << r1.value << ", r2 value: " << r2.value << std::endl;
// ----- 验证 = delete(禁止拷贝)-----
// Resource r3(r1); // ❌ 编译错误:拷贝构造已删除
// Resource r3;
// r3 = r1; // ❌ 编译错误:拷贝赋值已删除
// ----- 验证 = delete(拦截隐式转换)-----
r1.setValue(100); // ✅ 匹配 int 版本
// r1.setValue(99.9); // ❌ 编译错误:setValue(double) 已删除,精确匹配 double 导致重载决议失败
std::cout << "Final r1 value: " << r1.value << std::endl;
return 0;
}
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/m0_73457176/article/details/164795572



