注意返回函数内部的变量(C++)

 这个问题是一个很经典的问题,返回局部函数内部变量的值。当然优秀的程序员自然很清楚,但是对于一些小细节,也难免会犯上一些简单的错误。一般我们会通过直接需要接受返回值的对象放入函数的参数里面如: 

CopyObject(A& a1,A &a2)

{

   a2.a=a1.a;a2.b=a1.b;

}

 

 一般使用上述的方法来成功修改a2的值。

反过来我们写这样一个函数,打算同样实现复制的功能如下:

A& CopyObject(A& a1)// 注意这里的& 引用符号

{

   A temp;

  temp.a=a1.a;

  temp.b=a1.b;

  return temp;

}

 

调用如下:

 A a1(100,99);

 A a2=CopyObeject(a1);

 

 初步一看,这应该没有什么问题吧 ,自己思考一分钟吧!..............................................

 不知道你有没有想明白,在你明白之前,我们再来看一个这样的复制函数

 A CopyObject(A& a1)

{

   A temp;

  temp.a=a1.a;

  temp.b=a1.b;

  return temp;

}

 

  这个函数和上面那个复制函数唯一一处不一样的就是返回的值的不同,甚至函数体都是相同,那到底那一个可以成功呢。第一个函数是有问题的。 先做实验。

本人在windows7+vs2010 已经linux+gcc上分别做了实验。

在windows7+vs2010上是可以编译通过的,但是会发现a2的值完全是随机的内存数据。这说明了什么呢? 说明了a1所在的内存单元被释放了。

在linux+gcc 提示了警告 然后就是编译不过。

这里提出这些主要是想明白一个问题,(本人对linux下调试不是很熟悉,我在windows下进行了调试)。跟踪A类的析构函数,看到底是什么时候

对象a1被释放了。结果发现在return temp 这句语句返回之前,对象a1就已经释放了。然后为什么第一个返回不是引用的函数确实是可以复制成功

呢?

接下来就是属于楼主本人的见解,如果有错误的地方,请指正。

 首先明白的是c++中的引用和指针之间的关系,大家说法不一样,在我自己觉得,c++的应用的作用和指针完全是一样的,但是具体怎么实现的,

那要看编译器怎么样处理了,假如有机会的话,我在接下来文章中希望从汇编中探寻下这个问题。

在这个前提上,我得出了以下假设来解释为什么返回引用,复制会不成功。

1. 首先不管是返回什么引用也好,形参也好,局部函数的变量都是会被释放的,这与跟踪的结果一直,两个复制函数都在return语句返回之前,

   调用了对象的析构函数。

2.这里把引用当成指针,那么函数的返回值都是在栈中的,关键就在这里了,return 返回之前 指针自然是压入所指向的地址咯,然而形参不一

  样压入的则是整个对象。

 

好了问题就在这里了,在执行复制的时候,一个是指针,一个是栈中直接保存了对象。这样就明白为什么返回应用,复制不成功了吧。

 最后总结下:

 在调用函数修改参数的内容时候需要考虑一下几点

 第一 尽量讲要修改的参数以指针或者应用的方式放到修改函数中,这样最为保险。

 第二 如果要一定要使用返回值来修改的时候,那就要明确,一定不要返回指针以及应用,老老实实的用最原始的方法返回,这个时候

  就不要考虑参数栈操作的影响咯。

 

真实原创作品,问题小,但是确实常会遇到,希望有用!!

 

posted @ 2012-07-12 11:37  奔跑的兔子  阅读(3121)  评论(3编辑  收藏  举报