delete在C++中通过= delete声明实现编译期禁用函数,而非运行时禁用;最常见用途是成对删除拷贝构造函数和拷贝赋值运算符以防止意外拷贝,尤其适用于资源管理类。

delete在C++中不是用来“禁用函数”的操作符
它本身不提供禁用能力,而是通过显式删除函数声明(即delete函数声明)来让编译器拒绝调用——本质是编译期拦截,不是运行时禁用。
如何用= delete禁止拷贝构造和赋值
这是最常见也最实用的场景:防止对象被意外拷贝。尤其在资源管理类(如封装了FILE*、unique_ptr或自定义句柄)中必须显式禁用。
- 必须写在类内部,作为成员函数声明;
= delete要放在声明末尾,不能带函数体 - 声明位置不影响效果,但习惯上与默认/其他特殊成员函数放在一起(如紧接
public:后或靠近default声明) - 如果只删拷贝构造,不删拷贝赋值,编译器仍可能生成隐式拷贝赋值;建议成对删除
class NonCopyable {
public:
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};
为什么= delete比私有化+不定义更可靠
老式写法(C++98风格)是把拷贝函数设为private且不提供定义,靠链接失败报错。但这种方式有漏洞:
- 友元函数或类内代码仍可调用私有拷贝函数
- 某些模板实例化可能绕过访问检查,导致静默行为异常
-
= delete是硬性编译错误,无论调用位置、是否友元、是否在模板中,一律拒之门外 - 错误信息更明确,直接指出“attempting to reference a deleted function”
哪些函数适合用= delete禁用
核心原则:只要语义上不该存在,就应主动删除,而非依赖“没人会调用”的侥幸。
立即学习“C++免费学习笔记(深入)”;
- 不支持移动语义的类,显式删除
NonCopyable(NonCopyable&&) = delete和operator=(NonCopyable&&) = delete - 避免隐式类型转换:把单参构造函数标记为
explicit,若连显式转换都不允许,就= delete掉那个构造函数 - 模板类中排除不支持的类型:例如容器类的
push_back(T&&)对std::vector<bool></bool>特化中可删掉不适用的重载 - 禁止某些整数类型的隐式构造:
MyClass(int) = delete;能拦住MyClass x = 42;,但留着MyClass(long)则仍可通过MyClass x(42L);构造
注意:= delete不能用于析构函数(除非你真想让对象无法销毁——这会导致严重问题),也不能用于operator new/operator delete的全局重载(虽语法允许,但极易引发未定义行为)。


















