条款6:若不想使用编译器自动生成的函数,就该明确拒绝
若我们需要如下需求:
地产中介商会认位自己卖的房子是独一无二的,无法复制的
class HomeForSale{};
HomeForSale h1;
HomeForSale h2;
HomeForSale h3(h1); //不想让这句话通过编译
h1 = h2; //不想让这句话通过编译
我们不想上述两句话能够执行成功!但是如果我们不写相应的拷贝构造和=重载,则编译器会帮我们默认添加。所以就出现一下解决方案,分别分析一下好坏。
1、copy构造函数和copy assignment操作符声明为private,并且实现他们。
- 优点:我们阻止了编译器私自创建该版本,阻止用户调用它
- 缺点:并不绝对安全,因为成员函数和friend函数仍然可以调用该私有函数。
2、copy构造函数和copy assignment操作符声明为private,仅提供声明而不实现。
优点:不仅阻止编译器私自创建和用户调用,而且保证若有成员函数和friend函数使用他们的话,会报链接错误。
缺点:链接错误太迟了,能不能提前到编译期间报错?
3、专门设计一个为了阻止拷贝的基类,进行私有继承该类。
代码例子如下:
class Uncoyable
{
protected:
Uncoyable(){}
~Uncoyable(){}
private:
Uncoyable(const Uncoyable&);
Uncoyable& operator=(const Uncoyable&);
};
class HomeForSale : private Uncoyable //注意是私有继承
{
//...
//不再需要声明拷贝构造和=操作符重载
};
这种方法原理是什么呢?
答: 只要任何人尝试拷贝HomeForSale对象,编译器试着生成一个copy构造和=运算符重载,但是这些生成版本会尝试调用基类Uncoyable的拷贝,但是因为基类Uncoyable的拷贝是私有的,所以该操作直接在编译期间被编译器给拒绝了!
总结: 为了驳回编译器自动提供的机能,可将相应函数声明为私有且仅声明不实现。或者像使用Uncoyable这样的基类私有继承也是一种方式!
结尾: 我是航行的小土豆,喜欢我的程序猿朋友们,欢迎点赞+关注哦!希望大家多多支持我哦!有相关不懂问题,可以留言一起探讨哦!
如有引用或转载记得标注哦!