三五零法则是C++资源管理的指导原则:三法则要求自定义析构、拷贝构造、拷贝赋值三者之一时需全部显式定义;五法则在C++11后增加移动构造和移动赋值;零法则推荐委托给标准RAII类型,避免手动管理。

“三五零法则”是C++中关于类资源管理的一组指导原则,它告诉你在什么情况下需要手动定义哪些特殊成员函数,以确保类的行为正确、安全,尤其在涉及动态内存、文件句柄、互斥锁等资源时。
Rule of Three(三法则)
适用于C++11之前。当类中需要自定义析构函数(~T())、拷贝构造函数(T(const T&))或拷贝赋值运算符(T& operator=(const T&))中的任意一个时,通常三个都需要显式定义。
原因在于:默认生成的拷贝操作是浅拷贝,若类持有裸指针或独占资源,不重写就会导致双重释放、悬空指针或资源泄漏。
- 写了自定义析构函数 → 说明类管理了资源
- 有资源 → 拷贝时不能简单复制指针,得深拷贝或明确禁止拷贝
- 所以拷贝构造和拷贝赋值也必须同步处理,否则行为不一致
Rule of Five(五法则)
C++11引入移动语义后升级为“五法则”。除上述三个外,还需考虑移动构造函数(T(T&&))和移动赋值运算符(T& operator=(T&&))。
立即学习“C++免费学习笔记(深入)”;
如果类支持移动(比如内部有std::unique_ptr、动态数组),且你已写了析构/拷贝相关函数,那么移动操作也应明确实现或禁用——否则编译器可能生成默认移动函数,而它们会执行位移(bitwise move),对含裸指针的类依然危险。
- 显式定义移动函数,可高效转移资源,避免不必要的拷贝
- 若类逻辑上不可移动(如绑定到某个硬件句柄),就用
= delete禁用 - 注意:只声明移动函数,编译器将不再生成默认拷贝函数(除非你显式要求)
Rule of Zero(零法则)
现代C++的推荐实践:尽量不写任何特殊成员函数。让类的成员全部使用“符合三五法则”的类型(如std::vector、std::string、std::unique_ptr),由它们自己管理资源。
这样编译器自动生成的默认特殊成员函数就是正确的——因为所有成员都已正确实现了移动/拷贝/析构逻辑。
- 把资源管理封装在专用小类里(RAII类型),业务类只组合它们
- 零法则不是“什么都不管”,而是“把责任委托给标准库或靠谱的工具类”
- 例外:需要定制语义(如写日志、验证不变量)时,仍可加少量逻辑,但避免直接操作裸资源
本质上,“三五零”不是硬性规定,而是帮你识别资源管理意图的检查清单。写代码时先问一句:这个类是否拥有并独占某种资源?如果是,就按规则补全;如果否,优先走零法则。
基本上就这些。










