关于返回引用的思考

[ 事情起因 ]

一天在写代码的时候,突然想到返回对象的引用好像可以提高程序的执行效率,但在调试下面代码的时候发现一运行就会报错。

 

而如果将上面程序中 Fun() 函数的返回类型改为 vector<char> ,即去掉引用,则程序运行正常。为什么呢?持着怀疑的态度,又测试了下面的代码:

编译之,发现 IDE 有一个 warning ,不理会它,运行之,没有报错正确地显示了运行结果。这又是怎么回事呢?

 

[ 分析原因 ]

其实解决这个问题的关键就是,要知道函数中声明的局部对象,它的生命周期到哪里结束。没错,函数中声明的对象只在函数内部可见。但是代码 [2] 的结果如何解释呢?出现这样的结果也许只能说明是 IDE 的问题,对于代码 [2] 有可能已经回收了内存,但是并没有修改里面的值;而在代码 [1] 中,对于 vector ,则直接回收并覆盖里面的内容。

 

 

 

[ 调试证明 ]

编写下面代码,运行结果说明, IDE 在函数返回以后并不会覆盖简单类型的局部对象的内存。

分别调试查看代码 [1] 中函数原型为 int Fun() int& Fun() 所对应的汇编代码:

 


[ 得出结果 ]

当函数原型为 int Fun() 时,会将返回值 mov 到寄存器 eax 中保存,退出 Fun 后再 mov a 中。
当函数原型为 int& Fun() 时,会将返回值的地址保存在 eax 中,退出 Fun 后再通过此地址读取数据到 a 中。

因此,代码 [1] 中犯了一个严重的错误, Fun() 函数返回了一个局部对象的引用。当函数 Fun() 执行完毕后,其中的局部对象所占的内存会被销毁,其中所存储的数据也就不再存在了。此时如果再使用此函数的返回值,即返回的引用类型对象的值,程序将会出现错误。

 

[ 结论 ]

以前在书上好像读到过,当返回一个对象的时候,如果返回的不是引用,会自动调用构造函数再创建一个临时的对象。我在这里可能存在误解,本以为返回引用可以提高效率。现在得出结论:不要返回局部对象的引用;但可以返回一个局部对象 ( 实际上是返回了一个局部对象的拷贝,实际的局部对象“可能 [1] ”已经不再存在了 )

 

[1] “可能”的意思是,由于某些编译器的缘故,当函数执行完毕后,其中的局部对象的值可能依然存在,见代码 [2] [ 调试证明 ]

[2] 关于此问题,我曾发布的一个帖子

http://topic.csdn.net/u/20100323/16/45af3458-7e29-4632-8fd0-bef584091029.html?seed=160051105&r=64133769#r_64133769


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值