@lishuhuakai
2016-11-05T00:26:03.000000Z
字数 1777
阅读 1668
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_INCLUDED
namespace boost {
// Private copy constructor and copy assignment ensure classes derived from
// class noncopyable cannot be copied.
// Contributed by Dave Abrahams
namespace noncopyable_ // protection from unintended ADL
{
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private: // emphasize the following members are private
noncopyable( 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); // error
return 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
的坑可真多呢.