当前位置: 首页 > news >正文

三五法则的类的设计

C++ 的 三五法则(Rule of Three/Five)是指导类如何正确管理资源(如动态内存、文件句柄等)的核心准则,分为 三法则(C++98)和 五法则(C++11 引入移动语义后扩展)。以下是具体说明和代码示例:

三法则(Rule of Three)

如果一个类需要手动实现以下三者之一,则通常需要同时实现所有三个:
析构函数:释放资源(如 delete)

拷贝构造函数:定义深拷贝逻辑

拷贝赋值运算符:定义赋值时的深拷贝和资源释放

必要性:
默认生成的拷贝操作是浅拷贝,若类管理资源(如指针),会导致 双重释放 或 资源泄漏[citation:2][citation:6]。

示例代码(管理动态数组的类):
class RuleOfThree {
private:
int* data;
size_t size;
public:
// 构造函数
RuleOfThree(size_t s) : size(s), data(new int[s]) {}

// 1. 析构函数
~RuleOfThree() { delete[] data; }// 2. 拷贝构造函数(深拷贝)
RuleOfThree(const RuleOfThree& other) : size(other.size), data(new int[other.size]) {std::copy(other.data, other.data + size, data);

// 3. 拷贝赋值运算符

RuleOfThree& operator=(const RuleOfThree& other) {if (this != &other) {  // 防止自赋值delete[] data;     // 释放旧资源size = other.size;data = new int[size];std::copy(other.data, other.data + size, data);

return *this;

};

问题场景:
若未实现拷贝操作,默认浅拷贝会导致两个对象共享同一块内存,析构时重复释放[citation:2][citation:9]。

五法则(Rule of Five)

在 C++11 后,新增移动语义,扩展为以下五个函数:
析构函数

拷贝构造函数

拷贝赋值运算符

移动构造函数(noexcept)

移动赋值运算符(noexcept)

必要性:
移动操作通过“窃取”资源(如转移指针所有权)避免深拷贝开销,提升性能[citation:3][citation:6]。

示例代码(扩展上述类):
class RuleOfFive {
private:
int* data;
size_t size;
public:
// …(原有三法则实现)

// 4. 移动构造函数(转移资源所有权)
RuleOfFive(RuleOfFive&& other) noexcept 

data(other.data), size(other.size) {

    other.data = nullptr;  // 确保原对象析构安全

// 5. 移动赋值运算符

RuleOfFive& operator=(RuleOfFive&& other) noexcept {if (this != &other) {delete[] data;      // 释放旧资源data = other.data;size = other.size;other.data = nullptr;

return *this;

};

使用场景:
对象持有大量数据(如容器、图像缓冲区)时,移动操作显著减少拷贝成本[citation:4][citation:7]。

零法则(Rule of Zero)

现代 C++ 提倡通过智能指针(如 std::unique_ptr)或标准库容器(如 std::vector)自动管理资源,避免手动实现五法则[citation:4][citation:6]。

示例代码:
include

class RuleOfZero {
private:
std::unique_ptr<int[]> data; // 自动管理资源
size_t size;
public:
RuleOfZero(size_t s) : size(s), data(std::make_unique<int[]>(s)) {}
// 无需手动实现析构/拷贝/移动操作!
};

优势:
代码更简洁、安全,避免手动管理错误[citation:4][citation:6]。

总结
法则 适用场景 核心函数

三法则 C++98 资源管理类 析构函数、拷贝构造、拷贝赋值
五法则 C++11 需要高性能的资源管理类 三法则 + 移动构造、移动赋值
零法则 现代 C++(优先选择) 依赖智能指针或标准库,无需手动实现

推荐实践:
优先使用 零法则,必要时(如自定义资源管理)遵循 五法则[citation:4][citation:6]。

http://www.lryc.cn/news/579815.html

相关文章:

  • 供应链管理:指标评估方式分类与详解
  • Rust 中的返回类型
  • 云原生Kubernetes系列 | etcd3.5集群部署和使用
  • Day51 复习日-模型改进
  • TCP、HTTP/1.1 和HTTP/2 协议
  • 怎么更改cursor字体大小
  • JavaEE初阶第七期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(五)
  • ElasticSearch快速入门-1
  • MSPM0G3507学习笔记(一) 重置版:适配逐飞库的ti板环境配置
  • 服装零售企业跨区域运营难题破解方案
  • 如何将大型视频文件从 iPhone 传输到 PC
  • PoE 延长器——让网络部署更自由
  • 第十章:HIL-SERL 真实机器人训练实战
  • Docker拉取bladex 、 sentinel-dashboard
  • 【阿里巴巴JAVA开发手册】IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式,不要使用Windows格式。
  • Android BitmapRegionDecoder 详解
  • Java启动脚本
  • vue create 和npm init 创建项目对比
  • error MSB8041: 此项目需要 MFC 库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装它们。
  • React 渲染深度解密:从 JSX 到 DOM 的初次与重渲染全流程
  • 最快实现的前端灰度方案
  • 因果语言模型、自回归语言模型、仅解码器语言模型都是同一类模型
  • 同步(Synchronization)和互斥(Mutual Exclusion)关系
  • 【机器人】复现 DOV-SG 机器人导航 | 动态开放词汇 | 3D 场景图
  • (超详细)数据库项目初体验:使用C语言连接数据库完成短地址服务(本地运行版)
  • 敏捷开发在国际化团队管理中的落地
  • 二维码驱动的独立站视频集成方案
  • 碰一碰发视频源码搭建与定制化开发:支持OEM
  • 译码器Multisim电路仿真汇总——硬件工程师笔记
  • TensorFlow 安装使用教程