@lishuhuakai
2016-11-04T16:26:03.000000Z
字数 1777
阅读 1931
cpp
文章参考了这里http://blog.csdn.net/huang_xw/article/details/8248960
boost::noncopyable比较简单, 主要用于单例的情况.
通常情况下, 要写一个单例类就要在类的声明把它们的构造函数, 赋值函数, 析构函数, 复制构造函数隐藏到private或者protected之中, 每个类都这么做麻烦.
有noncopyable类, 只要让单例类直接继承noncopyable.
class noncopyable的基本思想是把构造函数和析构函数设置protected权限,这样子类可以调用,但是外面的类不能调用,那么当子类需要定义构造函数的时候不至于通不过编译。但是最关键的是noncopyable把复制构造函数和复制赋值函数做成了private,这就意味着除非子类定义自己的copy构造和赋值函数,否则在子类没有定义的情况下,外面的调用者是不能够通过赋值和copy构造等手段来产生一个新的子类对象的。
#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED#define BOOST_NONCOPYABLE_HPP_INCLUDEDnamespace boost {// Private copy constructor and copy assignment ensure classes derived from// class noncopyable cannot be copied.// Contributed by Dave Abrahamsnamespace noncopyable_ // protection from unintended ADL{class noncopyable{protected:noncopyable() {}~noncopyable() {}private: // emphasize the following members are privatenoncopyable( const noncopyable& );const noncopyable& operator=( const noncopyable& );};}typedef noncopyable_::noncopyable noncopyable;} // namespace boost#endif // BOOST_NONCOPYABLE_HPP_INCLUDED
给一个示例:
#include "tfun.h"class myclass: public boost::noncopyable{public:myclass(){};myclass(int i){};};int main(){myclass cl1();myclass cl2(1);// myclass cl3(cl1); // error// myclass cl4(cl2); // errorreturn 0;}
根据cpp的继承规则,如果子类以private的形式继承父类的话:
我这里有一个问题:
class A : boost::noncopyable{public:A () {}}class B : A{public:B() {}}
我的疑问是B类能够构造吗?我们来分析一下,A类以private的形式继承noncopyable,这意味着,noncopyable的构造函数和析构函数变成了A中的私有函数,是吧!
这样以来,B类构造的时候要调用A的构造函数,既然A的构造函数变成了private,那么B就不能构造了,不是吗?
推理似乎很漂亮,但是很遗憾,是错的,虽然很违反我们的直觉.
在effective c++提到过这个问题的解释,我在这里摘抄一下:
在子类对象(
derived class)对象的base class构造期间,该子类对象的类型是父类(base calss),而不是子类(derived class).在子类对象析构的时候这一条也成立.
至于为什么会有这么违反直觉的事情发生,可以查看effective c++的条款9:绝不在构造和析构过程中调用virtual函数.
结果显而易见,在B类调用A类的构造函数时,B类仍然是A类,所以可以访问noncopyable的构造函数.
好吧,cpp的坑可真多呢.