引用容易犯的错误。

由于对象a是个局部对象,因此当函数对象func结束后,局部对象a也就被删除了。由于对象a消失了,所以Func()函数返回的其实是一个并不存在的对象的别名。
用这个不存在的对象来调用该对象的函数get()。该函数会返回一个并不存在的对象的x成员。因此输出一个随机数。

如果这样,那输出就是23,为什么?

因为去掉引用符号后,返回方式变成了按值返回,而按值返回又会调用复制构造函数,复制一个对象a的副本,然后将这个副本再赋给r,r就是这个对象a的副本的别名。

下面举个例子说明这个:

VC6.0下输出结果:

跳转到func函数中!

调用构造函数创建一个对象

对象a的地址0012FF00

执行复制构造函数创建一个对象

执行析构函数

对象a的副本的地址:0012FF6C

23

执行析构函数!

 

看到这个结果相信会明白不少东西。但是与此同时,这里有个问题:

 

为什么对象a的副本的生命会一直持续到main函数结束呢?(上面最后一句输出:执行析构函数!就是对象a的副本的析构,所以有必要怀疑一下他的生命周期!)

这是因为对于引用而言,如果引用的是一个临时变量,那么这个临时变量的生存期会不少于这个引用的生存期。
(参见c++标准[class.temporary])

也就是说,直到main函数结束时,引用r的生存期结束,r所引用的临时变量的生存期才结束,由于r所引用的是一个对象,因此这时才会调用它的析构函数来释放内存。

PS;

顺便说一下,指针是没有这个特性的,假如将对象a的副本的地址赋给一个指针,那么在func函数返回对象a的副本的时候,就可以析构这个对象a的副本。

输出结果如下:

跳转到func函数中!

调用构造函数创建一个对象

对象a的地址0012FF0C

执行复制构造函数创建一个对象

执行析构函数

执行析构函数

对象a的副本的地址:0012FF78

23

分析:连续执行了两次析构函数,将对象a和他的副本所占用的内存全部释放掉了。

但是我们确实看到了get函数输出了对象a的副本的x成员为23

于此我们也知道对象a的副本已经被删除了啊,已经析构过了啊。为什么这里又输出了他的成员x的值呢?

::这是因为析构函数调用并析构某个对象后,只是告诉编译器这一块内存不再为某个对象独占了,你可以访问它,别的对象或者变量也可以访问它并使用该内存区域存储他们的数据,但是在他们使用之前,存放在该内存区域中的数据并没有删除,因此使用指针来访问该区域仍然能够得到未被修改的x的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值