Effective C++(6) 如何拒绝编译器的自动生成函数

问题聚焦:
如果不希望class支持某一成员函数,那么不声明和定义它就可以了,但是这一策略对与拷贝构造函数和重载赋值操作符并不起作用。
因为如果不声明它们,那么当尝试调用它们的时候,编译器会为你声明和定义它们。
这显然不是你所希望看到的。

方法:将这类你不想使用并且也不想编译器为你声明的函数声明为private, 而不实现它们。
原理:
编译器自动生成的函数都是public
声明一个函数可以阻止编译器自动生成该函数
令这个函数为private可以阻止人们调用它
缺陷:
member函数或friend函数可以调用它们,导致链接错误。
Demo:

class HomeForSale {
public:
    ... ...
private:
    ...
    HomeForSale(const HomeForSale&);
    HomeForSale& operator=(const HomeForSale&);
};


上面的方案虽然有一个小小的缺陷,但是还是可以让人接受的,毕竟链接错误不是那么的不可接受。
很多时候我们总是希望尽可能地找到错误,毕竟链接错误远不如编译错误那样相对容易解决一点。
这也是这个方案可以优化的地方(尽管我觉得很多时候可以不这么做)

方案二:在方案一的基础上,将链接期错误移至编译器。

先来看看demo.
Demo:

class Uncopyable {
protected:
    Uncopy() {}
    ~Uncopy() {}
private:
    Uncopyable (const Uncopyable&);
    Uncopyable& operator=(const Uncopyable&);
};
//  为了阻止编译的自动生成,我们唯一需要做的就是继承Uncopyable

class  HomeForSale: private Uncopyable {
    ......
};

原理:
当尝试拷贝操作时,编译器会尝试调用父类的对应的拷贝构造函数和重载赋值操作符,这些调用会被编译器拒绝,因为其base class的拷贝函数是private
从而报出编译错误。

小结:
为了阻止编译器的自动生成功能,可以将相应的成员函数声明为private并且不予实现。
使用向Uncopyable这样的base class也是一种做法。


参考资料:
《Effective C++ 3rd》

 

posted @ 2013-12-24 15:23  suzhou  阅读(220)  评论(0编辑  收藏  举报