Big Three+noncopyable

    三法则的要求在于,假如类型有明显地定义下列其中一个成员函数,那么程序员必须连其他二个成员函数也一同编写至类型内,亦即下列三个成员函数缺一不可。 [1]:
         析构函数(Destructor)
         复制构造函数(copy constructor)

         复制赋值运算符(copy assignment operator)

    无论何时你需要定义析构函数、复制构造函数、或赋值操作符三个中的任意一个,你也需要定义另外两个。它们三者间的互动性非常重要,其中一个存在,其它的通常也都必须要有。我们假设你的一个类有一个成员是指针。你定义了一个析构函数用于正确地释放空间,但你没有定义复制构造函数和赋值操作符。这意味着你的代码中至少存在两个潜在的危险,它们很容易被触发。

     当一个类持有某种资源的时候,三大件函数缺少了,编译器形成浅拷贝,那么会造成潜在的错误,比如动态分配的内存,浅拷贝只是拷贝地址值。

#include<iostream>
using namespace std;
class test{
public:
	void show(){
		cout<<*data_<<endl;
	}
	test(int data=10){
		data_=new int(data);
	}
	~test(){
		delete data_;
		cout<<"~test"<<endl;
	}
private:
	//test(const test&);
	//test& operator=(const test&);
private:
	int* data_;
};
int main(){
	test one;//正常输出与析构
	one.show();
	//test two=one;//析构异常,浅拷贝,只是将成员的值进行赋值,所以此时two.data_和one.data_具有相同的值,也即这两个指针指向了堆里的同一个空间
	//two.show();
	//test three(one);//析构异常
	//three.show();
	test four;//析构异常
	four=one;
	four.show();
	return 0;
}
          所以最好显示的给出三大件函数(深度拷贝),在某些情况下需要禁止类的拷贝与赋值,通用的方法是将拷贝构造函数和赋值操作设为私有化。boost的noncopyable就是这样的,自定义类A继承noncopyable后A将不允许拷贝与赋值(私有继承,public没什么意义).

class noncopyable
{
   protected:
      noncopyable() {}
      ~noncopyable() {}
   private: // emphasize the following members are private
      noncopyable( const noncopyable& );
      const noncopyable& operator=( const noncopyable& );
};
       noncopyable的基本思想是把构造函数和析构函数设置protected权限,这样子类可以调用,但是外面的类不能调用,那么当子类需要定义构造函数的时候不至于通不过编译。但是最关键的是noncopyable把copy构造函数和copy赋值函数做成了private,这就意味着除非子类定义自己的copy构造和赋值函数,否则在子类没有定义的情况下,外面的调用者是不能够通过赋值和copy构造等手段来产生一个新的子类对象的。

你可能感兴趣的:(big)