拷贝构造函数(深拷贝/浅拷贝)

  类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量,因此,类对象之间的复制较为复杂。

#include <iostream>
using namespace std;

class CExample 
{
private:
     int a;//成员变量

public:
     CExample(int b)//构造函数
         a=b;

     void Show ()//成员函数
           cout<<a<<endl;
};

int main()
{
     CExample A(100);
     CExample B=A;//调用默认的拷贝构造函数
     B.Show ();//输出100
     return 0;
}

  系统为对象B分配了内存,并将对象A复制给对象B,此过程调用默认的拷贝构造函数(浅拷贝)

#include <iostream>
using namespace std;

class CExample 
{
private:
    int a;

public:
    CExample(int b)//构造函数
        a=b;
    
    CExample(const CExample& C)//拷贝构造函数
        a=C.a;
    
    void Show ()
        cout<<a<<endl;
};

int main()
{
    CExample A(100);
    CExample B=A;//使用自定义的拷贝构造函数
    B.Show ();//输出100
    return 0;
} 

  系统为对象B分配了内存,并将对象A复制给对象B,此过程调用自定义的拷贝构造函数(浅拷贝)

浅拷贝和深拷贝

  在某些状况下,类内成员变量需要动态开辟堆内存,如果实行浅拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针

  深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源(堆,或者是其它系统资源);当这个类的对象发生复制过程的时候:

    重新分配资源,这个过程就是深拷贝

    没有重新分配资源,就是浅拷贝

#include <iostream>
using namespace std;

class CA
{
public:
  CA(int b,char* cstr)//构造函数
  {
   a=b;//初始化成员变量a
   str=new char[b];
         //从cstr地址开始且含有null结束符的字符串复制到
         //以str地址开始的字符串中
   strcpy(str,cstr);
  }

  CA(const CA& C)//拷贝构造函数
  {
   a=C.a;
   str=new char[a]; //深拷贝,重新分配资源
   if(str!=0)
    strcpy(str,C.str);
  }

  void Show()
   cout<<str<<endl;
  

  ~CA()//析构函数
   delete str;//释放分配的资源

private:
  int a;
  char *str;
};

int main()
{
 CA A(10,"Hello!");
 CA B=A;//调用自定义的拷贝构造函数
 B.Show();//输出Hello!
 return 0;
}      

  系统为对象B分配了内存,并将对象A复制给对象B,并为对象B重新分配了资源,此过程调用自定义的拷贝构造函数(深拷贝)

原文链接 https://www.cnblogs.com/BlueTzar/articles/1223313.html

原文地址:https://www.cnblogs.com/yongjin-hou/p/14526706.html