不好驯服的析构函数

不好驯服的析构函数

本文假定您对C++的面向对象机制有一些了解,并且对指针比较清楚。您可以随便转载,但是必须保证文章的完整性,并且注明出处。

很愿意和您交朋友:xiaobo68688@qq.com

注:想问我是学C还是C++的朋友就不要发邮件了,谢谢!

首先看一个深拷贝的例子

  可能我写的有点乱,成员变量包括一个指针,其实是一个数组,想要深拷贝。

所以我们需要重载拷贝构造函数。

初学C++的时候,直接记住了参数是引用类型,当时对语言没有深入的理解(虽然现在也不深入),也就没有往心里去,这些天模拟STL,遇到了好多关于深拷贝的问题,而且这问题出的很怪异(我会在下午提出),因此想到了拷贝构造函数,所以在这里需要深究一下。

拷贝构造函数的参数是引用类型。

我们可以试想一下不是引用的情况,也就是说,拷贝构造函数是下边这个样子:

参数传递的是一个对象,按值传递,那么这个对象就会被复制到right,复制的时候又会调用拷贝构造函数,那又会复制一个对象到第二次调用的这个拷贝构造函数里边,因此又需要第三次调用拷贝构造函数。。。想一下,是不是无限循环?

简单地说:传值需要调用拷贝构造函数,而不是引用类型的拷贝构造函数又需要调用拷贝构造函数。因此无限循环。

Ok,把引用的这个问题说明白,下边说一下我这几天遇到的这个问题:

请先看一段代码:

可以试着运行一下,在我电脑上边出现了下边这个错误

很恐怖的错误。呵呵,让我们详细分析一下。

第一次a.show()成功,说明对象a建立没有问题;b.show()失败,说明没有复制成功;第二次a.show()失败,说明a被修改了,可以猜想一下,是不是被调用了析构函数?

现在重载 的时候是按值传递,那么,我们传进去的是地址psize

之后是执行拷贝的函数,这个没啥问题,把right中的相关数据拷贝。

然后就开始执行析构函数了,首先析构的是传进来的参数,也就是right,由于rightp和主函数中ap相等,因此rightpdelete了也就是apdelete了,在这里,我们把主函数中的a不小心析构了一点点(把pdelete了)。因为函数的返回的是值,所以第二步析构的是(*this),这样,就把复制后的pdelete了。到这里,我们悲剧地把内存中所有的pdelete了。

所以,当再次输出ab的时候,全都是随机值。

细心的朋友可能会发现,当第二次输出ab的时候仍然是输出了10个,也就是开始的size值。asize10不难理解。由于析构函数是在函数返回后调用的,所以返回的bsize是不改变的(返回是在改变以前)。

我们试着改一下:

下边是我在参数上边加了&,这样,当再次输出a的时候没有错误

下边是在参数right和返回值都加了& 这样就没有错误了

正好符合我们的分析。

评论 115
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值