Effective C++读书笔记(4) (二)

2014-11-24 12:20:03 · 作者: · 浏览: 1
++ 的iostreams 库里,就有几个类用此方法防止拷贝。比如,标准库的实现中 ios_base,basic_ios 和 sentry,其拷贝构造函数和拷贝赋值运算符被声明为 private 而且没有被定义。

将这个窍门用到HomeForSale 上,很简单:

class HomeForSale {
public:
...

private:
...
HomeForSale(const HomeForSale&); // 只有声明
HomeForSale& operator=(constHomeForSale&);
};

你会注意到,我省略了函数参数的名称。参数名称并非必要,只不过大家总是习惯写出来。毕竟,函数不会被实现,更少会被用到,有什么必要指定参数名称呢?有了上述类定义,编译器将阻止客户拷贝 HomeForSale objects对象的企图,如果你不小心在成员函数或友元函数中这样做,连接器会提出抗议。

将连接时错误提前到编译时间也是可行的(早发现错误毕竟比晚发现好)。在一个为 prevent防止拷贝而特意设计的基类中,声明拷贝构造函数和拷贝赋值操作符为private就可办到。这个基类本身非常简单:

class Uncopyable {
protected:

Uncopyable() {} // 允许derived对象构造和析构
~Uncopyable() {}

private:
Uncopyable(const Uncopyable&); // 但阻止copying
Uncopyable& operator=(const Uncopyable&);
};

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

class HomeForSale: private Uncopyable {
... // class不再声明copy构造函数或copy赋值操作符

};

Uncopyable 的实现和使用包含一些微妙之处,比如,从 Uncopyable 继承不必是 public的,而且 Uncopyable 的析构函数不必是virtual的。因为 Uncopyable 不包含数据,所以它符合emptybase class optimization的条件,但因为它总是扮演基类,因此使用这项技术可能导致多重继承。通常,你可以忽略这些微妙之处,而且仅仅像此处演示的这样来使用 Uncopyable。你还可以使用在 Boost里的noncopyable类。

· 为了拒绝编译器自动提供的机能,将相应的member functions(成员函数)声明为 private,而且不要给出 implementations(实现)。使用一个类似 Uncopyable 的 base class(基类)是方法之一。



摘自 pandawuwyj的专栏