条款6:不想使用编译器自动生成的函数,就要明确拒绝!

每一个对象都是独一无二的,如果不想其被复制,我们就希望其复制以失败收场。
如一座房屋出售HomeForSale类:

1 HomeForSale h1;
2 HomeForSale h2;
3 HomeForSale h3(h1);//我们希望这俩语句以失败告终
4 h1=h2;//

通常情况下,我们使用某个功能时,调用相对应的函数即可,如果这个函数没有被定义,则编译器会提示错误。但是这一情况不适用复制构造函数和赋值构造函数。因为条款5已经指出,如果你不声明它们,而有人希望调用它们,编译器就会替你声明。
这就不太好了,不管我们是否声明它们,我们定义的某个类还是支持这种copy行为,但是这是要明确禁止的!
答案的关键是,编译器产出的所有函数都是public的,为阻止这些函数的出现,我们就要自行声明其为private,这样就阻止了编译器私自创建其专属版本。这样的话别人就不可以调用它们。
一般而言这个做法不是绝对安全,因为成员函数和友函数可以调用已经声明为private的copy特性函数。
将成员函数定义为private而不去实现它们,这一招被大家接受,在C++ iostream库中阻止copy行为。在ios_base,basic_ios,和sentry中,无论哪个,其复制构造函数和赋值构造函数都被声明为private而没有定义。
但是这个错误出现在连接期,如果我们希望错误提示越早出现越好,那么将其提前到编译器无疑是最棒的。

 1 Uncopyable
 2 {
 3 public:
 4 
 5 protected:
 6 Uncopyable();
 7 ~Uncopyable();//基类的析构函数不一定非得是virtual
 8 
 9 private:
10 Uncopyable(const Uncopyable&);
11 Uncopyable& operator=(const Uncopyable&);
12 };
13 class HomeForSale:private Uncopyable
14 {
15 
16 };

如果基类(Uncopyable)有复制构造函数和赋值构造函数而且为private的。那么其子类(HomeForSale)的对象如果被copy,那么,编译器就会创建一个复制构造函数和赋值构造函数,而且还会尝试调用其父类版本(复制和赋值),这时,编译器会拒绝调用,因为父类的复制和赋值是private的。

posted @ 2017-05-22 17:06  弗莱曼飞侠  阅读(243)  评论(0编辑  收藏  举报