[
事情起因
]
一天在寫**的時候,突然想到返回物件的引用好像可以提高程式的執行效率,但在除錯下面**的時候發現一執行就會報錯。
而如果將上面程式中
fun()
函式的返回型別改為
vector
,即去掉引用,則程式執行正常。為什麼呢?持著懷疑的態度,又測試了下面的**:
編譯之,發現
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]
關於此問題,我曾發布的乙個帖子
關於函式返回引用的分析?
一 函式返回值和返回引用是不同的 函式返回值時會產生乙個臨時變數作為函式返回值的副本,而返回引用時不會產生值的副本。1.普通函式返回值 c primer中這樣寫 函式的返回值用於初始化在呼叫函式處建立的臨時物件。在求解表示式時,如果需要乙個地方儲存其運算結果,編譯器會建立乙個沒有命名的物件,這就是臨...
關於返回型別為引用
在c 中,函式經常返回型別為引用。這裡呢,我主要說的一點是,當返回型別為引用時,我們可以用引用來接受,也可以用普通變數來接受。include pch.h include using namespace std int a 19 int lyy int main 結果如下 1919 f c about...
C 關於返回引用和非引用的區別
這幾天剛好遇到乙個題目。我們跳過背景,直接切入正題。template class t class hypervectoriterator public std iterator std random access iterator tag,t 這是類的定義,這個類的目的是繼承iterator,然後完...