關於返回引用的思考

2021-05-22 01:37:01 字數 1649 閱讀 8231

[

事情起因

]

一天在寫**的時候,突然想到返回物件的引用好像可以提高程式的執行效率,但在除錯下面**的時候發現一執行就會報錯。

而如果將上面程式中

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,然後完...