某些类可能不允许被拷贝,我们可能会试图去不声明copy构造函数和copy assignment操作符来让用户无法copy,但这毫无意义,因为编译器还是会生成它们。
解决的关键在于编译器所自动生成的这些函数都是public的,如果我们声明一个private的copy构造函数以及copy assignment运算符,并且不去定义它们(以防止友元访问),那么这个类自然就无法copy了。
当你把它们声明为private时,如果用户试图去拷贝,此时编译器会报错,如果我们通过友元或者在成员函数内试图调用它们,因为没有定义,此时轮到连接器发出警告。
当然,越早报错越好,那能不能把连接期错误移至编译期呢?答案是可行的。
为了实现上述理想,我们需要借助一个base class,它什么也不干,就是为了阻止copy。1
2
3
4
5
6
7
8class Uncopyable{
protected:
Uncopyable() {}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable)
}
如果我们需要令某个类无法被copy,那我们只需要让该类私有继承Uncopyable即可(关于采用何种方式继承最为恰当,详见Effective C++ 38 39)
当友元或者成员函数试图拷贝时,编译器会试着生成copy构造函数或者copy assignment操作符,这两个函数又会去调用base class中的版本,发现调用失败,编译报错。
Uncopyable的设计颇为微妙,值得仔细揣摩,比如说继承方式,析构函数,以及空类优化等诸多方面。但在本章,我们只关心它的作用:阻止拷贝。
总结
为了拒绝编译器生成的某些函数,我们可以将其设为private且不予实现。或者令该类继承类似于Uncopyable这样的基类。