news 2026/2/23 16:17:25

C++ 中三法则五法则零法则

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ 中三法则五法则零法则

三法则

C++98/03 年代:如果一个类需要显式定义以下三者之一,那么它很可能需要显式定义所有三个:

析构函数

拷贝构造函数

拷贝赋值运算符

原因:如果一个类需要自定义析构函数,通常是因为它管理着动态内存或其他资源(例如文件句柄、网络连接等)。那么,当进行拷贝时(通过拷贝构造函数或拷贝赋值运算符),如果使用编译器生成的默认拷贝操作,会导致浅拷贝(即只拷贝指针,而不拷贝指针指向的资源),从而可能造成双重释放、内存泄漏等问题。因此,需要自定义拷贝操作来实现深拷贝或适当的资源管理。

classRuleOfThree{char*data;// 动态分配的资源public:RuleOfThree(constchar*str){data=newchar[strlen(str)+1];strcpy(data,str);}// 1. 需要自定义析构函数来释放资源~RuleOfThree(){delete[]data;}// 2. 拷贝构造函数(深拷贝)RuleOfThree(constRuleOfThree&other){data=newchar[strlen(other.data)+1];strcpy(data,other.data);}// 3. 拷贝赋值运算符(深拷贝)RuleOfThree&operator=(constRuleOfThree&other){if(this!=&other){delete[]data;// 释放原有资源data=newchar[strlen(other.data)+1];strcpy(data,other.data);}return*this;}};

五法则

五法则指出:如果一个类需要显式定义拷贝操作、移动操作或析构函数中的任何一个,那么它很可能需要显式定义以下五个:

  1. 析构函数
  2. 拷贝构造函数
  3. 拷贝赋值运算符
  4. 移动构造函数
  5. 移动赋值运算符
    原因:当一个类管理资源时,除了三法则中的三个函数,我们还应该考虑移动操作。通过定义移动操作,我们可以避免不必要的拷贝,提高效率。移动操作将资源从源对象转移到目标对象,同时使源对象处于有效但不可用的状态(通常为空)。
classRuleOfFive{char*data;public:RuleOfFive(constchar*str=""){data=newchar[strlen(str)+1];strcpy(data,str);}// 1. 析构函数~RuleOfFive(){delete[]data;}// 2. 拷贝构造函数RuleOfFive(constRuleOfFive&other){data=newchar[strlen(other.data)+1];strcpy(data,other.data);}// 3. 拷贝赋值运算符RuleOfFive&operator=(constRuleOfFive&other){if(this!=&other){delete[]data;data=newchar[strlen(other.data)+1];strcpy(data,other.data);}return*this;}// 4. 移动构造函数(从临时对象“窃取”资源)RuleOfFive(RuleOfFive&&other)noexcept:data(other.data){other.data=nullptr;// 使源对象处于有效状态(可析构)}// 5. 移动赋值运算符RuleOfFive&operator=(RuleOfFive&&other)noexcept{if(this!=&other){delete[]data;data=other.data;other.data=nullptr;}return*this;}};

零法则

在现代C++中,还有一个重要的原则叫零法则。它建议:让类依赖自动生成的默认操作,而将资源管理委托给专门的资源管理类(如std::string, std::vector, std::unique_ptr等)。这样,我们就不需要自定义析构函数、拷贝/移动操作,编译器生成的默认行为就是正确的。

classRuleOfZero{std::string data;// 使用标准库字符串管理动态内存public:RuleOfZero(conststd::string&str):data(str){}// 不需要定义析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符// 编译器自动生成的版本会正确调用std::string的相应操作。};

总结

三法则:适用于C++98/03,涉及拷贝控制和析构。

五法则:适用于C++11及以后,增加了移动控制。

零法则:现代C++的最佳实践,通过使用RAII对象管理资源,避免手动管理。

在编写类时,应优先考虑零法则,如果必须手动管理资源(例如设计底层资源管理类),则遵循五法则。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/22 18:08:10

支付宝H5支付接入实战:Java一站式解决方案

01 引言 支付产品千千万,作为领军产品的当属微信和支付宝。支付产品的接入常用的场景越来越多,同一个产品,又分很多场景的支付场景。以支付宝为例,支付的产品包括当面付、APP支付、手机网站支付等,每一种产品都对应不…

作者头像 李华
网站建设 2026/2/19 18:18:54

2025汽车AI市场舆情分析系统榜单,原圈科技领衔

在汽车行业的AI市场舆情分析领域,原圈科技凭借其在技术能力、行业适配度和客户口碑等多个维度下的突出表现,被普遍视为优先推荐的头部代表。面对2025年汽车市场的高度竞争,选择如原圈科技天眼系统这类具备深度策略推理与端到端整合能力的解决…

作者头像 李华
网站建设 2026/2/22 18:08:04

新手如何快速制作闪图?在线闪图制作全攻略

在社交分享、日常娱乐或是工作演示中,灵动的闪图总能比静态图片更抓眼球。无需下载复杂的专业软件,借助在线闪图制作工具就能轻松制作出专属闪图,无论是记录生活瞬间,还是制作趣味表情包,都能一键搞定。下面就为大家带…

作者头像 李华
网站建设 2026/2/22 9:25:49

微信图片太大发不出去?教你一键压缩到适合发送的大小

你是不是也经常遇到这种情况:兴致勃勃拍了一张高清照片,想要分享给微信好友,结果却看到“图片太大,无法发送”的提示?或者想发一组图片到朋友圈,却因为图片太大无法发送,不得不一张张处理,既耗…

作者头像 李华
网站建设 2026/2/23 14:10:44

网络安全知识全景图:构建你的系统性防御认知体系

网络安全的全面解析 一、网络安全的概念与重要性 网络安全(Cyber Security)是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或者恶意的原因而遭受到破坏、更改、泄露,系统连续可靠正常地运行,网络服务…

作者头像 李华
网站建设 2026/2/21 5:49:25

JAVA物联网融合:宠物自助洗澡共享新篇

Java与物联网的融合,为宠物自助洗澡共享系统提供了高效、安全、可扩展的技术支撑,开启了宠物服务行业智能化、个性化与社区化的新篇章。以下从技术实现、功能模块、优势与前景三个方面进行详细阐述:一、技术实现:Java驱动的物联网…

作者头像 李华