您的位置:首页 > 运维架构

Big Three+noncopyable

2013-11-16 10:24 357 查看
    三法则的要求在于,假如类型有明显地定义下列其中一个成员函数,那么程序员必须连其他二个成员函数也一同编写至类型内,亦即下列三个成员函数缺一不可。 [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 Three+noncopyabl