注意返回函數內部的變量(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 返回之前 指針自然是壓入所指向的地址咯,然而形參不一

  樣壓入的則是整個對象。

 

好了問題就在這里了,在執行復制的時候,一個是指針,一個是棧中直接保存了對象。這樣就明白為什么返回應用,復制不成功了吧。

 最后總結下:

 在調用函數修改參數的內容時候需要考慮一下幾點

 第一 盡量講要修改的參數以指針或者應用的方式放到修改函數中,這樣最為保險。

 第二 如果要一定要使用返回值來修改的時候,那就要明確,一定不要返回指針以及應用,老老實實的用最原始的方法返回,這個時候

  就不要考慮參數棧操作的影響咯。

 

真實原創作品,問題小,但是確實常會遇到,希望有用!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM