深拷贝的缺点_C++深入理解浅拷贝和深拷贝,码了一年才懂

关于对象的拷贝,大部分时间我们用的都是浅拷贝,比如赋值符号(“=”)以及memcpy()等。那么既然浅拷贝这么简单,为什么还需要深拷贝呢?两者之间的区别又是什么呢?两者分别在什么情况下使用呢?

可能很多人写了很久的代码,都还只知道对象赋值而不知道深拷贝,导致很多时间出现莫名bug而且找不到原因。今天就让我们深入的来了解一下两者的区别。

浅拷贝

例如:

class MyClass{public:MyClass(int x);~MyClass();int a ;private:};MyClass::MyClass(int x){this->a = x ;}MyClass::~MyClass(){}void main(){int b = 100 ;//浅拷贝MyClass my1(10) ;MyClass my2 = my1;//浅拷贝MyClass my3(20) ;memcpy(&my3,&my1,sizeof(MyClass));//浅拷贝cout<

运行结果是都是10,以上三个都是浅拷贝,浅拷贝的原理就是:将 被拷贝对象所在内存中的数据按照二进制位(Bit)复制到新对象所在的内存,这种默认的拷贝行为就是浅拷贝。其原理图如下:

a4f549822462133a2621d0c0398ae16a.png

浅拷贝的缺点

上面的例子中,MyClass都是基本类型,这种浅拷贝用起来是没有什么问题,但是C++的难点是什么?对,就是指针。如果MyClass成员中有指针类型怎么办?是不是也用浅拷贝呢?

我们在Mycalss类中新增一个char* str 成员,还是按上面那样用浅拷贝的方式拷贝对象。

class MyClass{public:MyClass(int x,char * s);~MyClass();int len;int a ;char* str ;private:};MyClass::MyClass(int x,char* s ,int length){//这里注意不能直接this->str = s ;因为指向的是常量,常量内存我们是delete不了的this->len = lenth ;this->a = x ;this->str = new char[this->len] ;memcpy(str,s,this->len);}MyClass::~MyClass(){}void main(){int b = 100 ;//浅拷贝MyClass my1(10,"i love u") ;MyClass my2 = my1;//浅拷贝MyClass my3(20,"i do not love u") ;memcpy(&my3,&my1,sizeof(MyClass));cout<

我们发现my2.str和my3.str打印出来的是一堆乱码。这是为什么呢?请看下面的示意图:

fa46105742a932bcef9cc23f693b5e10.png

浅拷贝复制的只是指针变量,但是这个指针所管理的内存还是my1的。所以当你通过my1删除了str所管理的内存,那么在my2和my3中的str就找不到这块内存原来的内容了;

深拷贝的实现

既然浅拷贝在对象中存在着管理其他内存的指针时,在对象的内存释放时会出现野指针的问题,那么如何去避免呢?很简单,除了会将原有对象的所有成员变量拷贝给新对象,还会为新对象再分配一块内存,并将原有对象所持有的内存也拷贝过来。

e94b701c40e7184e70d44f32c7904afd.png

实现代码:

#include #include #include #include using namespace std;class MyClass{public:MyClass(int x,char * s,int len);MyClass(const MyClass& myclass);~MyClass();int len ;int a ;char* str;private:};MyClass::MyClass(int x, char* s,int length){this->len = length ;this->a = x ;this->str = new char[this->len] ;memcpy(str,s,this->len);}MyClass::MyClass(const MyClass& myclass){this->len = myclass.len ;this->a = myclass.a ;this->str = new char[this->len] ;memcpy(this->str,myclass.str,this->len);}MyClass::~MyClass(){}void main(){cout<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值