欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

C++Primer13章学习笔-三/五法则

时间:2023-06-01
三/五法则

什么是三法则

如果需要析构函数,则一定需要拷贝构造函数和拷贝赋值操作符。

什么是五法则

在较新的 C++11 标准中,为了支持移动语义,又增加了移动构造函数和移动赋值运算符,这样共有五个特殊的成员函数,所以又称为“C++五法则”;

如果需要析构函数,则一定需要拷贝构造函数和拷贝赋值操作符。

原因:

类中出现了指针类型的成员。有指针类型的成员,我们必须防止浅拷贝问题,所以,一定需要拷贝构造函数和赋值操作符,这两个函数是防止浅拷贝问题所必须的。

一个对象拥有额外的资源(指针指向的内存),但另一个对象使用合成的拷贝构造函数也同时拥有这块资源。当一方对象被销毁后,析构函数释放了资源,这时另一个对象便失去了这块资源(但程序员还不知道)。

class HasPtr{public:HasPtr(const std::string& s = std::string()) :ps(new std::string(s)), i(0) {}//HasPtr(const HasPtr& hasPtr);//HasPtr& operator=(const HasPtr& hasPtr);~HasPtr() { delete ps; };private:std::string* ps;int i;};HasPtr f(HasPtr hp) // 使用了合成拷贝构造函数,使得hp.ps 和 p.ps 指向相同内存{HasPtr ret = hp; // 使用了合成拷贝构造函数,使得ret.ps 和 hp.ps 指向相同内存return ret; // retrurn 之后,ret和hp 会被释放资源,调用析构函数 析构函数会delete ps 导致p.ps 的内存被释放。}HasPtr p("some value");f(p); // 当f结束时,p.ps 指向的内存被释放HasPtr q(p); // p和q都指向无效内存

如果一个类需要自定义析构函数,几乎可以肯定它也需要自定义拷贝赋值运算符和拷贝运算符

需要拷贝操作的类也需要赋值操作,反之亦然,但不一定意味着需要析构函数 与三之法则不同的是,不提供移动构造函数和移动赋值运算符通常不是错误,但会导致失去优化机会。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。