「生活可以更简单, 欢迎来到我的开源世界」
  1. 拒绝编译器自动提供的机制
  2. 总结
Item6-若不想使用编译器自动生成的函数,就该明确拒绝
2021-01-01
」 「

Item6-若不想使用编译器自动生成的函数,就该明确拒绝

拒绝编译器自动提供的机制

不想要编译器自动生成拷贝构造函数和拷贝赋值运算符,你就必须自己声明,如果你不想要拷贝操作被使用,那你可以将它们声明为 private 。

将拷贝构造函数和拷贝赋值运算符声明为私有的。通过显式声明一个成员函数,可以防止编译器生成它自己的版本,而且将这个函数声明为私有的,可以防止别人调用它。

一般而言这个做法并不绝对安全,因为member 函数和友元函数还是能够调用你的 private 函数。除非你十分聪明地不定义它们,那么,当有人不小心地调用了它们,在 link-time(链接时)会出现一个连接错误(linkage error)。

“将成员函数声明为 private 而且故意不实现它们”这一伎俩被大多数人接受,因而被用在 C++ iostream 程序库中阻止 copying 行为。

class HomeForSale {
public:
...
private:
...
//@ declarations only
HomeForSale(const HomeForSale&); //参数名称并非必要,当这个函数不实现了也就没必要写出来了
HomeForSale& operator=(const HomeForSale&);
};

对于上面的类定义,编译器将阻止客户拷贝对象的企图,如果你不小心在成员或友元函数中这样做了,连接程序会提出抗议。

通常会专门设计一个阻止 copying 动作的 base class 内:

class Uncopyable {
protected:
Uncopyable() {}
~Uncopyable() {}

private:
//@but prevent copying
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};

为求阻止 HomeForSale 对象被拷贝,唯一需要做的就是继承 Uncopyable:

class HomeForSale: private Uncopyable {      
...
};

这样行得通,因为只要任何人(包括member 函数或 friend 函数)尝试拷贝 HomeForSale 对象,编译器便尝试着生成一个 copy 构造函数和一个 copy assignment 操作符,这些编译器生成的函数会尝试调用基类的对应函数,而这些调用将被拒绝,因为基类的拷贝函数是 private的。

Uncopyable 的实现和使用颇为微妙:

总结

<⇧>