类的拷贝行为是可以定义的,比如一个系列唯一的ID号,再如一个类共享的动态资源等。C++需要三个法则就可以完成拷贝行为的控制,他们分别是三个“特殊”的函数:
- 析构函数
- 拷贝构造函数
- 拷贝赋值函数
完全没有必要定义所有的三法则,因为编译器将会默默编写这些函数。对于析构函数,基本上什么都不做,这也就是说你需要手动调用delete删除哪些动态分配的内存;对于拷贝构造、拷贝赋值,编译器只是单纯地将类内non-static对象逐成员拷贝,特别的,指针成员拷贝则是拷贝其指向而不是所指(浅拷贝)。
在《类拷贝规则——三/五法则》已经解释过,下面的trick:
- 如果你要定义析构函数,你肯定要定义对应的拷贝赋值和拷贝构造
- 如果你定义了拷贝构造,那么你一定要定义赋值构造
在作者写这本书时,如果你需要屏蔽某个合成函数,你可以通过将其设置为private;除此,当你定义了自己的三法则中的一个时,编译器将不再继续为你提供合成剩余法则的服务,可有的时候你又确实需要合成服务,在此之前除了手工完成没有别的办法。
C++11支持了两个关键字,delete和default。前者解决了屏蔽任务,后者解决了再次服务问题。类的数据成员类型将会影响编译器合成三法则,如果一个类有数据成员不饿能默认构造、拷贝、复制或销毁,则对应的成员函数将会被定义为删除的;对于引用成员或无法默认构造的const成员的类,编译器将不会合成默认构造、默认拷贝构造、默认拷贝赋值。
PS:C++11其实是五法则,多了移动构造和移动赋值。
条款06 若不想使用编译器自动生成的函数,就该明确拒绝条款05已经做过说明,对于不支持delete编译器,至少有两种解决方案:
- 只声明不实现放在private中
- private继承
前者仍然存在风险,因为友元和成员函数仍然可以调用,从而产生错误,最好就是使用delete。
条款07 为多态基类声明virtual析构函数 7.1 任何class只要带有virtual函数,几乎确定也需要一个virtual析构#include
enum class clockType
{
Atomic,
Water,
Wrist
};
class TimeKeeper
{
public:
TimeKeeper() {};
~TimeKeeper() { std::cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?