C++三五法则

三五法则主要内容

在一个类中,编译器可以为我们合成的函数有默认构造函数,拷贝构造函数,拷贝赋值构造函数,移动构造函数,移动赋值构造函数。这意味着我们有时候可以不用自己去实现这些内容。但是,在默认合成的函数无法满足我们的需求时,我们就要手动合成之。大多数情况下,我们除了要自己实现需要的函数外,还必须实现部分其他的函数,以确保我们的函数能够正确的工作。三五法则就是用来为这样的类内部函数成员的涉及提供指导的。其具体内容可概括为:

  • 需要析构函数的类也需要拷贝构造函数和拷贝赋值函数;
  • 需要拷贝构造函数,则同样需要拷贝赋值构造函数;
  • 析构函数不能是删除的;
  • 如果一个类有删除的或不可访问的析构函数,那么其默认和拷贝构造函数会被定义为删除的;
  • 如果一个类有const或引用成员,则不能使用合成的拷贝赋值操作。

需要析构函数的类也需要拷贝构造函数和拷贝赋值函数

若一个类需要析构函数,通常说明合成的构造函数无法释放所管理的资源,比如需要手动释放管理的内存。

需要拷贝构造函数,则同样需要拷贝赋值构造函数;

需要拷贝操作代表这个类在拷贝时需要进行一些额外的操作。 赋值操作 <<< = >>> 先析构+拷贝,所以拷贝需要的赋值也需要。反之亦然。

析构函数不能是删除的

如果类的析构函数是删除的,那么成员便无法销毁。所以在程序中不能定义这个类的对象。可以动态分配该对象并获得其指针,但无法销毁这个动态分配的对象(delete 失效)。

#include <iostream>
#include <string>

typedef unsigned int uint;
using namespace std;

class Person{
	public:
		Person(uint myage=18, string myname="hhh")
		{
			age=myage;
			name=new string(myname);
		}
		uint age;
		string* name;
		~Person()=delete;
};

int main(int argc, char** argv){
	Person a;//析构函数是删除的,不能够定义其对象

	delete a;
	return 0;
} 

报错输出:
[Error] use of deleted function ‘Person::~Person()’

#include <iostream>
#include <string>

typedef unsigned int uint;
using namespace std;
class Person{
	public:
		Person(uint myage=18, string myname="hhh")
		{
			age=myage;
			name=new string(myname);
		}
		uint age;
		string* name;
		~Person()=delete;
};

int main(int argc, char** argv){
	Person* a=new Person();//这里可以编译通过
	delete a;//这里报错
	return 0;
} 

报错输出:
[Error] use of deleted function ‘Person::~Person()’

如果一个类有删除的或不可访问的析构函数,那么其默认和拷贝构造函数会被定义为删除的

如果没有这条规则,可能会创造出无法被删除的对象。 理论上来说,当析构函数不能被访问时,任何静态定义的对象都不能通过编译器的编译,所以这种情况只会出现在与动态分配有关的拷贝/默认构造函数身上。

如果一个类有const或引用成员,则不能使用合成的拷贝赋值操作

原因很简单,const或引用成员只能在初始化时被赋值一次,而合成的拷贝赋值操作会对所有成员都进行赋值。显然,它不能赋值const和引用成员,所以合成的拷贝构造函数不能被使用,即会被定义为删除的。

本质上,当不可能拷贝、赋值、或销毁类的所有成员时,类的合成拷贝控制函数就被定义成删除的了。

【参考】
C++三五法则
这个总结大部分都是从这个参考里面摘录而来的,感觉原文档记录更加详细,推荐阅读原文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值