2012-09-04 20 views
0

我對TDM-GCC 4.6.1編譯器的右值引用做了一些實驗,並做了一些有趣的觀察,我無法用理論來解釋。我想請那裏的專家幫我解釋一下。右值引用基元整數是短命還是長命?

我有一個非常簡單的程序,不與對象,但INT原語處理和已定義的2個功能: foo1(返回由右值引用的局部變量)和 foo2的(返回由值的局部變量)

#include <iostream> 

using namespace std; 

int &&foo1(); 
int foo2(); 

int main() 
{ 

int&& variable1 = foo1(); 
//cout << "My name is softwarelover." << endl; 
cout << "variable1 is: " << variable1 << endl; // Prints 5. 
cout << "variable1 is: " << variable1 << endl; // Prints 0. 

int&& variable2 = foo2(); 
cout << "variable2 is: " << variable2 << endl; // Prints 5. 
cout << "variable2 is still: " << variable2 << endl; // Still prints 5! 

return 0; 
} 

int &&foo1() { 

int a = 5; 
return static_cast<int&&>(a); 
} 

int foo2() { 

int a = 5; 
return a; 
} 

似乎foo1返回的值和變量1接收到的值在一段時間後消失 - 也許是幾毫秒的短暫時間。請注意,我已經通過評論它禁止cout打印「我的名字是軟件愛好者」。如果我允許該聲明運行,結果會有所不同。看起來好像是因爲「cout < <」我的名字是softwarelover「引入的時間延遲。」5變爲0.

上面是如何rvalue引用應該在引用由函數返回的函數時引用的基本整數而不是按值返回嗎?爲什麼它是0,爲什麼不是垃圾?

另請注意,變量2從未出現無論我用cout打印多少次!variable2指的是一個函數返回值的原始整數,而不是通過引用的返回。

謝謝。

+3

你怎麼知道0不是垃圾? –

+0

我希望我們不會有這個錯誤接受的答案:http://stackoverflow.com/questions/9467872/addresses-and-lifetime-of-rvalue-references-or-of-xvalues-in-general –

+0

永遠不會返回自動對象由右值引用。移動僅由移動構造函數執行,而不是由'std :: move'執行,而不是僅通過將右值綁定到右值引用。 [相關常見問題](http://stackoverflow.com/questions/3106110/) – fredoverflow

回答

5

右值引用仍然是引用。函數返回後,對函數局部變量的引用無效。你很幸運,在函數調用之後,任何時候你的右值引用都是5,因爲在函數返回後它在技術上是無效的。

編輯:我正在擴展我的答案,希望有些人會發現一些額外的細節有用。

函數內定義的變量是函數局部變量。該變量的生命週期僅限於它聲明的函數內部。當函數返回時,您可以將其視爲「銷燬」,但它並未真正銷燬。如果它是一個對象,那麼它的析構函數將被調用,但保存該變量的內存仍然存在。對該變量的任何引用或指針仍指向內存中的同一位置,但該內存已被重新使用(或可能在將來某個不確定的時間重新使用)。

舊的值(在你的情況'5')仍然會在那裏一段時間,直到有東西出現並覆蓋它。沒有辦法知道這些值會持續多長時間,並且在函數返回後的任何時間內都不應該依賴它們。考慮到一旦函數返回,任何引用(或指針)都會使局部變量無效。比喻說,如果你敲門,你很可能不會找到新的租客。

+0

經過我們所有的討論之後,我想我現在可以爲變量1爲何死亡以及爲什麼變量2生存的問題制定一個答案。 函數foo1()返回右值引用。在這個表達式中,返回的右值引用是未命名的,因此是一個xvalue。 int && variable1 = foo1(); 我們知道xvalue是「即將到期」的值。因此,儘管被變量1捕獲,但xvalue如預期般簡單地消失(5至0)。另一方面,int && variable2 = foo2();另一方面,int && variable2 = foo2();相當於說 int && variable2 = 5;這是完全沒問題的。因此,它靠着。 :-) – softwarelover

相關問題