c++的浅拷贝与深拷贝

一、什么是深浅拷贝?
浅拷贝:编译器自己创建的直接赋值
深拷贝:我们自己在堆区重新开辟空间进行赋值

 
二、使用浅拷贝会出现什么问题?
 
一旦有数据开辟在堆区,再使用浅拷贝,就会造成堆区内存重复释放,进行了非法操作
 
假如没有堆区数据

#include<iostream>
using namespace std;
class Person
{
 public:
 Person()
 {
  cout<<"Person的默认构造函数调用"<<endl; 
 } 
 Person(int age)
 {
  cout<<"有参构造函数!"<<endl;
  m_age=age;
 }


Person()
 {
  cout<<"Person的析构函数调用"<<endl;
 }
 int m_age;
} ;
void test01()
{
    Person p1(18);
 Person p2(p1);
 cout<<"p1的年龄:"<<p1.m_age<<endl;
 cout<<"p2的年龄:"<<p2.m_age<<endl;
}
int main()
{
    test01();
 system("pause");
 return 0;
}

现在数据是完全正确的
在这里插入图片描述 

那么我们下面加入堆区数据

m_Height=new int(height);

#include<iostream>
using namespace std;
class Person
{
 public:
 Person()
 {
  cout<<"Person的默认构造函数调用"<<endl; 
 } 
 Person(int age,int height)
 {
  cout<<"有参构造函数!"<<endl;
  m_age=age;
  m_Height=new int(height);
 }
 ~Person()
 {
  //析构函数,将堆区的数据释放干净 
  if(m_Height!=NULL)
  {
   delete m_Height;
   m_Height=NULL;
  }
  cout<<"Person的析构函数调用"<<endl;
 }
 int m_age;
 int* m_Height;
} ;
void test01()
{
    Person p1(18,180);
 Person p2(p1);
 cout<<"p1的年龄:"<<p1.m_age<<"身高为:"<<*p1.m_Height<<endl;
 cout<<"p2的年龄:"<<p2.m_age<<"身高为:"<<*p2.m_Height<<endl;
}
int main()
{
    test01();
 system("pause");
 return 0;
}

编译器就会报错在这里插入图片描述
 
三、原因
如果使用浅拷贝,那么拷贝前后指向了堆区的同一块内存地址,按照先创建的后析构原则,p2通过拷贝构造被创建,他会先被释放,使用delete之后,0x0011的堆区内存已经被释放,p1调用析构函数的时候,发生了重复释放堆区内存,进行了非法操作
在这里插入图片描述 

四、解决
解决浅拷贝的问题,就要使用深拷贝,在堆区重新开辟一块新的内存

Person(const Person&p)
 {
  cout<<"拷贝构造函数!"<<endl;
  m_age=p.m_age;
  m_height=new int(*p.m_height); 
 }

这样的话,在释放的时候,就会p1释放0x0011,p2释放0x0022,就不会出现重复释放的问题了
在这里插入图片描述

附上全部代码

#include<iostream>
using namespace std;
class Person
{
 public:
 Person()
 {
  cout<<"Person的无参构造函数调用"<<endl; 
 } 
 Person(int age,int height)
 {
  cout<<"有参构造函数!"<<endl;
  m_age=age;
  m_height=new int(height);//new表示新建一个对象 
 }
 Person(const Person&p)
 {
  cout<<"拷贝构造函数!"<<endl;
  m_age=p.m_age;
  m_height=new int(*p.m_height); 
 }
 ~Person()
 {
  cout<<"Person的析构函数调用"<<endl;
  if(m_height!=NULL)
  {
   delete m_height;
  } 
 }
 int m_age;
 int* m_height;
} ;
void test01()
{
    Person p1(18,180);
 Person p2(p1);
 cout<<"p1的年龄:"<<p1.m_age<<"身高:"<<*p1.m_height<<endl;
 cout<<"p2的年龄:"<<p2.m_age<<"身高:"<<*p2.m_height<<endl;
}
int main()
{
    test01();
 system("pause");
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值