c++深拷贝/浅拷贝

独自空忆成欢 提交于 2020-02-01 16:30:18

  拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的参数(对象的引用)是不可变的(const类型)。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。

一.什么时候对调用拷贝构造函数?

  1. 对象以值传递的方式传入函数参数
  2. 对象以值传递的方式从函数返回
  3. 对象需要通过另外一个对象进行初始化

二. 浅拷贝(位拷贝)和深拷贝

  浅拷贝:也称位拷贝,编译器只是直接将指针的值拷贝过来,结果多个对象共用同一块内存,当一个对象将这块内存释放掉之后,另一些对象不知道该块空间已经还给了系统,以为还有效,所以在对这段内存进行操作的时候,发生了访问违规。 

  深拷贝:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配

 防止默认拷贝发生

  通过对对象复制的分析,我们发现对象的复制大多在进行“值传递”时发生,这里有一个小技巧可以防止按值传递——声明一个私有拷贝构造函数。甚至不必去定义这个拷贝构造函数,这样因为拷贝构造函数是私有的,如果用户试图按值传递或函数返回该类对象,将得到一个编译错误,从而可以避免按值传递或返回对象。

// 防止按值传递  
class CExample   
{  
private:  
    int a;  
  
public:  
    //构造函数  
    CExample(int b)  
    {   
        a = b;  
        cout<<"creat: "<<a<<endl;  
    }  
  
private:  
    //拷贝构造,只是声明  
    CExample(const CExample& C);  
  
public:  
    ~CExample()  
    {  
        cout<< "delete: "<<a<<endl;  
    }  
  
    void Show ()  
    {  
        cout<<a<<endl;  
    }  
};  
  
//全局函数  
void g_Fun(CExample C)  
{  
    cout<<"test"<<endl;  
}  
  
int main()  
{  
    CExample test(1);  
    //g_Fun(test); 按值传递将出错  
      
    return 0;  
}   

三 拷贝构造函数的几个细节

1. 拷贝构造函数里能调用private成员变量吗?
  不受private的限制
2. 以下函数哪个是拷贝构造函数,为什么?

X::X(const X&);      
X::X(X);      
X::X(X&, int a=1);      
X::X(X&, int a=1, int b=2); 

解答:对于一个类X, 如果一个构造函数的第一个参数是下列之一:

  1. X&
  2. const X&
  3. volatile X&
  4. const volatile X&

且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数.

X::X(const X&);  //是拷贝构造函数      
X::X(X&, int=1); //是拷贝构造函数     
X::X(X&, int a=1, int b=2); //当然也是拷贝构造函数  

3. 一个类中可以存在多于一个的拷贝构造函数吗?
解答:类中可以存在超过一个拷贝构造函数。

class X {   
public:         
  X(const X&);      // const 的拷贝构造  
  X(X&);            // 非const的拷贝构造  
};  

注意,如果一个类中只存在一个参数为 X& 的拷贝构造函数,那么就不能使用const X或volatile X的对象实行拷贝初始化.

class X {      
public:  
  X();      
  X(X&);  
};      
  
const X cx;      
X x = cx;    // error  

如果一个类中没有定义拷贝构造函数,那么编译器会自动产生一个默认的拷贝构造函数。
这个默认的参数可能为 X::X(const X&)或 X::X(X&),由编译器根据上下文决定选择哪一个。


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!