這個問題是乙個很經典的問題,返回區域性函式內部變數的值。當然優秀的程式設計師自然很清楚,但是對於一些小細節,也難免會犯上一些簡單的錯誤。一般我們會通過直接需要接受返回值的物件放入函式的引數裡面如:
copyobject(a& a1,a &a2)
一般使用上述的方法來成功修改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 返回之前 指標自然是壓入所指向的位址咯,然而形參不一
樣壓入的則是整個物件。
好了問題就在這裡了,在執行複製的時候,乙個是指標,乙個是棧中直接儲存了物件。這樣就明白為什麼返回應用,複製不成功了吧。
最後總結下:
在呼叫函式修改引數的內容時候需要考慮一下幾點
第一 盡量講要修改的引數以指標或者應用的方式放到修改函式中,這樣最為保險。
第二 如果要一定要使用返回值來修改的時候,那就要明確,一定不要返回指標以及應用,老老實實的用最原始的方法返回,這個時候
就不要考慮引數棧操作的影響咯。
真實原創作品,問題小,但是確實常會遇到,希望有用!!
返回函式的函式
廖雪峰python課程裡的 作業的兩種實現方法 1.def createcounter a 0 def counter nonlocal a nonlocal 函式是 引用外部函式 的函式 a 1 a 1等同於a a 1 return a return counter countera create...
返回函式之迴圈變數問題
返回函式之迴圈變數問題 一 學習要點 1.返回函式建立的時候不被執行,呼叫的時候才被執行 2.返回函式不要應用任何迴圈變數或者後續會發生變化的變數 3.如果一定要引用迴圈變數,方法是在建立乙個函式,用該函式的引數繫結迴圈變數當前的值,無論該迴圈變數後續如何更改,已繫結的函式引數的值不變 二 學習 結...
c 函式未返回函式值
test0 include include using namespace std int add int a,int b int main int argc,char ar int main int argc,char ar int main int argc,char ar int main i...