C++ =default和=delete

什么是合成版本

合成版本就是指编译器自己生成的版本。如合成拷贝函数,合成拷贝赋值重载,合成析构函数
合成拷贝函数 能够将被拷贝的对象的成员的值拷贝到新对象
合成拷贝赋值函数 能够将赋值运算符的右侧对象的非static成员赋予左边对象的对应成员。
合成析构函数为空

=default 显式要求合成版本

我们可以使用控制成员定义为=default来显式地要求编译器生产合成的版本

  • 当我们在类内使用=default修饰成员的声明时,合成的函数会隐式地声明为内联的。
  • 当我们在类外使用=default,就是不希望合成地函数是内联的。
class Sales_data{
public:
	Sales_data() = default;
	Sales_data(const Sales_data&) = default;
	Sales_data& operator=(const Sales_data &);
	~Sales_data() = default; 
}
Sales_data& operator=(const Sales_data&) = default;

=delete 阻止拷贝

有些情况,不想要对象能够被拷贝(比如iostream对象)

struct Nocopy{
	Nocopy() = default;//使用合成的默认构造函数
	Nocopy(const Nocopy&) = delete;//阻止拷贝
	Nocopy &operator=(const Nocopy&) = delete;//阻止赋值
	~Nocopy() = default; 		//使用合成的析构函数
};
  • 和=default不同,=delete必须出现在函数第一次声明的时候。
  • 和=default不同,我们可以对任何函数指定=delete(我们能只对编译器可以合成的默认构造函数和拷贝控制成员使用default)
  • 析构函数不能被删除,如果析构函数被删除,就无法销毁此类型的对象了。

对于删除了析构函数的类型,虽然我们不能定义这种类型的变量或成员,但是能动态分配这种类型的对象,只不过是无法释放。

struct NoDtor{
	NoDtor() = default;
	~NoDtor() = delete;
};

NoDtor nd; //错误:NoDtor的析构函数是删除的
NoDtor *p = new NoDtor();//正确,但是不能deleteNoDtor
delete p;//错误,NoDtor的析构函数是删除的

合成的拷贝控制成员可能是删除的

我们知道,如果我们没有定义拷贝控制成员,编译会为我们定义合成的版本。类似的,如果我们没定义构造函数,编译器会为我们定义合成的构造函数。但是对某些类而言,编译器将这些合成的成员定义为删除的函数。

  • 如果类的某个成员的析构函数是删除的或者不可访问的(如private),则类的合成析构函数被定义为删除的
  • 如果类的某个成员的拷贝构造函数是删除的或者不可访问的,则类的合成拷贝构造函数被定义为删除的。如果类的某个成员的析构函数是删除的或者不可访问的,则类合成的拷贝构造函数也被定义为删除的。
  • 如果某个成员的拷贝赋值运算符是删除的或者不可访问的,或是类有一个const的,或者引用成员,则类的合成拷贝赋值运算符是删除的。
  • 如果类的某成员的析构函数是删除的或者不可访问的,或者是类有一个引用成员,它没有类内初始化器,或是类内有一个const成员,它没有类内初始化器且其类型为显式定义默认构造函数,则类内的构造函数被定义为删除的。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值