C++深拷贝和浅拷贝详解

嵌入式技术

1372人已加入

描述

C++ 深拷贝和浅拷贝

当类的函数成员存在指针成员时会产生深拷贝和浅拷贝和问题。

在进行对象拷贝时会使用 默认拷贝构造函数默认进行浅拷贝 ,即只会拷贝指针的值,新拷贝的指针与原来的指针指向同一内存;

指针

浅拷贝带来的问题是, 调用析构函数时,会导致堆内存被多次释放 ,因为这些指针 指向的是同一份内存

深拷贝会对 指针指向的内存也进行拷贝 ,解决了指针悬挂的问题。

指针

关于类对象拷贝的情况,需要注意:

  • 函数的参数为对象 ,实参传递给形参的时候,或 函数返回值为一个对象 ,函数内对象传递给返回值时,系统均通过拷贝构造函数实现。
  • 浅拷贝带来的隐患是, 多次释放指向同一块堆内存的不同指针时,会造成内存多次释放的问题 。可以使用智能指针 std::shared_ptr 解决这个问题。

Example

#include < iostream >
using namespace std;

class Randy {
 private:
  int age;
  char *id;

 public:
  Randy();
  ~Randy();
};

Randy::Randy() { id = new char(10); }
Randy::~Randy() {
  delete id;
  id = nullptr;
}

int main() {
  {
    Randy q1;
    Randy q2(q1);
  }

  return 0;
}

运行该程序:

(base) qiancj@SanJieJiYuan:~/codes/test$ ./randy 
free(): double free detected in tcache 2
Aborted (core dumped)

增加深拷贝 拷贝构造函数

#include < iostream >
#include < cstring >
using namespace std;

class Randy {
 private:
  int age;
  char *id;

 public:
  Randy();
  ~Randy();
  Randy(const Randy &randy);//自定义拷贝构造函数
};

Randy::Randy() { 
    id = new char(13);
    cout < < "Randy ctor" < < endl;}
Randy::~Randy() {
  cout < < "~Randy : delete id " < < id < < endl;
  delete id;
  id = nullptr;
}

Randy::Randy(const Randy &randy)
{
 age = randy.age;
 id = new char(13);
 // 内存拷贝
 memcpy(id, randy.id, strlen(randy.id));
 cout < < "deep copy Randy" < < endl;
}

int main() {
  {
    Randy q1;
    Randy q2(q1);
  }

  return 0;
}

运行结果:

(base) qiancj@SanJieJiYuan:~/codes/test$ ./randy 
Randy ctor
deep copy Randy
~Randy : delete id 
~Randy : delete id

因为深拷贝是对内存的拷贝,因此释放时会释放不同对象对应的堆内存。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分