首页 > 代码库 > 条款6:不想使用编译器自动生成的函数,就要明确拒绝!
条款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的。
条款6:不想使用编译器自动生成的函数,就要明确拒绝!