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

跟我学C++中级篇——三五法则

一、三五法则

三五法则,这个叫着有点上头,说实话,这个三五法则,未来会不会变成三六或者四七法则,没人知道,反正现在是三五法则。在《c++Primer》第四版中,叫三法则,在第五版第13.1.4章节则叫做了三五法则。
什么是三五法则?分开来讲,三法则是指c++编译器会默认生成类的三个基本拷贝操作函数即:拷贝构造函数、拷贝赋值运算符和析构函数。五法则则是在前面的基础上,c++11后提供的移动构造函数和移动赋值运算符。这几个类一般情况下是一个整体,如果需要其中一个,其它也需要。
一般写c++程序的人员经常是写个构造函数就OK了,比如在Qt提供的自定义类中,就没有析构函数,就这意思。但你只定义了其中一个比如析构函数或者拷贝构造函数,程序也运行的很好。是的,这没有问题,因为基本上也遇不到故意去用这种意外情况的情况。(正如书所提到的只定义了析构函数,但未定义拷贝和赋值操作,浅拷贝造成的二次析构同一指针的问题)。

二、说明

1、需要显示定义的析构函数也需要定义拷贝构造函数和赋值构造函数(或者说定义其中一个,其它五个一般都要定义)
正如前面分析,对于合成的拷贝系列函数,会产生浅拷贝的问题,这时析构函数会产生多次释放同一内存指针的问题,也就UB问题产生了。但事实上基本上这种行为就是崩溃。

class A
{
public:char * s_ = nullptr;A(){s_ = new char[10];}~A(){delete s_;}
};int main(void)
{A a;A b(a);return 0;
}

这个问题并不罕见,在几乎所有的c++入门书籍中,都会提到类似问题,因为它更是用来说明拷贝构造函数的,但是基本上没有人会把其和析构函数联系起来。
2、需要拷贝操作的类也需要赋值操作,反之亦然
这个就很好理解了,朋友一生一起走(逻辑行为一致)。特别是在面试时,经常问这个行为到底调用拷贝构造还是赋值操作。这里重温一个小问题,为什么拷贝构造函数参数必须是一个引用,const有没有必要?前者是因为非引用会产生递归循环,编译错误;后才则不一定是必须的,但一直是这么做。
3、析构函数不可删除
因为删除析构函数会导致在栈上的对象无法释放,所以,它会产生一种奇妙的行为,如果不想让开发者在栈上使用这个对象就可以private它。换句话说,可以动态分配这个对象,并手动释放相关的资源。

4、如果类成员有删除或不可访问的析构函数(或拷贝、赋值),则类本身合成析构函数(拷贝、赋值)自动定义为删除的
这个法则的意思是严格限制定义规则,防止因为自动合成的拷贝系列函数产生漏洞。

class A
{
private:~A();
};
class B
{A a;
};

5、如果类对象有const或者引用成员则不能使用合成的拷贝赋值操作
这个好理解,就是对cv限定符的一种安全处理。

三、总结

正如人们经常讲的,有人在替你负重前行。这句话用在c++这不太恰当,但是大概意思相当。有的时候儿开发者可能什么都没有做,但为了保障基本的编译实现,c++标准还是要求编译器在后台要完成一些基础的动作。而且随着标准的发展,这些东西可能还会增加。看看c++11中推出的移动构造就明白了,没有什么一成不变的东西,要想更好的活在当下,就必须变革,这才是王道。
上周把大佬的名字搞错了,结果出了乌龙笑话。亏得众位兄弟及时指出,特此感谢。这些兄弟是:
多喝水多运动,孤蓬,Emma,捉虫少年小鹏向您发起挑战。
再次感谢上面的朋友,并对乌龙事件表示歉意。

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

相关文章:

  • aardio:用 WebView 模仿 mdict 界面
  • linq中的操作符
  • 数据结构【哈夫曼树】
  • SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接
  • deepspeed zero3
  • 代驾小程序怎么做
  • 探索 AJAX 技术:实现动态数据交互的前端利器
  • 深度学习Redis(3):主从复制
  • php笔记1
  • 2023 ChinaJoy 圆满闭幕,FairGuard游戏加固亮相 BTOB 展区
  • 数据规约策略
  • 服务器带宽独享跟共享有什么区别103.36.166.x
  • 【cluster_block_exception】写操作elasticsearch索引报错
  • chaitin-Nginx+Docker
  • 具体面试题
  • Logback ThresholdFilter LevelFilter
  • python+django+mysql项目实践二(前端及数据库)
  • Kubernetes高可用集群二进制部署(五)kubelet、kube-proxy、Calico、CoreDNS
  • 拦截器对接口细粒度权限校验
  • 计算机科技历史纵横:8月6日的十大里程碑
  • 知识图谱实战应用23-【知识图谱的高级用法】Neo4j图算法的Cypher查询语句实例
  • C++ 头文件函数大全
  • 智慧物流园区整体架构方案【46页PPT】
  • llama2模型下载
  • C高级【day4】
  • 【前端实习生备战秋招】—HTML 和 CSS面试题总结(一)
  • 【从零学习python 】02. 开发工具介绍
  • Python:Spider爬虫工程化入门到进阶(2)使用Spider Admin Pro管理scrapy爬虫项目
  • CubeMap convert into Octahedral思路
  • vue项目实战-脑图编辑管理系统kitymind百度脑图