C++ | 深拷贝和浅拷贝

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);//拷贝构造函数,const防止对象被改变
};

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 

欢迎关注公众号【三戒纪元】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值