首页 > 学院 > 开发设计 > 正文

boost::noncopyable 禁止拷贝

2019-11-06 06:22:56
字体:
来源:转载
供稿:网友

当我们定义一个类时,我们显示地或隐式地指定在此类型的对象拷贝、移动、赋值和销毁时做什么。一个类通过定义五种特殊的成员函数来控制这些操作,包括:拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符和析构函数。我们称这些操作作为拷贝控制操作。

如果一个类没有定义所有的这些拷贝控制成员,编译器会自动为它定义缺失的操作。很多类会忽略这些拷贝控制操作。但是,对一些类来说,依赖这些操作的默认设定会导致灾难。

有时候,当我们定义某个类时,我们可能不希望我们定义的类进行拷贝操作。为此,我们可以采用将拷贝构造和拷贝赋值声明为PRivate(私有)的,这样的话就能禁止类进行拷贝操作。不过,这样做的话,显得比较麻烦。为此,boost中就提供noncopyable,我们通过继承noncopyable就可以实现禁止拷贝了。

下面是boost::noncopyable类的实现。在实现中,将构造函数和析构函数声明为保护,这样不会影响noncopyable作为基类,也避免外部构建一个noncopyable实类。

namespace noncopyable_  // protection from unintended ADL{	class noncopyable 	{ 	protected: 		noncopyable() {} 		~noncopyable() {} 		private: 		// emphasize the following members are private 		noncopyable( const noncopyable& ); 		noncopyable& Operator=( const noncopyable& ); 	};		typedef noncopyable_::noncopyable noncopyable;}; 

 那么,问题来了。为什么将noncopyable作为基类,能使派生类实现禁止拷贝? 这是因为,在派生类拷贝过程中,主要分为2部分:首先,调用基类的复制构造函数完成基类部分的复制,然后再复制派生类的部分。由于基类的拷贝构造函数和拷贝赋值运算符声明为私有的,派生类无法访问。所以,在第一部分的时候已经失败了,这就成功的禁止派生类的拷贝功能。

我们可以尝试写如下的测试代码,编译环境VS2013。

当我们未使用boost::noncopyable时:

class MyClass {public:	MyClass()  {}	~MyClass() {}};int main(void){	MyClass CMySrc;	MyClass CMyDest;	MyClass CMyDest1(CMySrc);	CMyDest = CMySrc;	return 0;}

此时,编译成功。

当我们使用boost::noncopyable时:

#include <boost/noncopyable.hpp>class MyClass   :  public boost::noncopyable{public:	MyClass()  {}	~MyClass() {}};int main(void){	MyClass CMySrc;	MyClass CMyDest;	MyClass CMyDest1(CMySrc);	//错误	CMyDest = CMySrc;		//错误	return 0;}此时,编译不通过。说明确实禁止了类的拷贝功能。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表