#include <iostream>
#include <string>
using namespace std;
const string& Func()
{
return "123";
}
int main()
{
string s = Func();
cout << s << endl;
return 0;
}
const 引用不是会提升临时变量的生命期吗? 为什么返回函数内的临时变量会报错了? 我对const引用的理解哪里错了吗?
#include <iostream>
#include <string>
using namespace std;
const string& Func(const string& s)
{
return s;
}
int main()
{
string s = Func("123");
cout << s << endl;
return 0;
}
但是这段代码就可以了。 Func函数参数绑定到一个临时变量,然后返回这个临时变量的const引用,就没有问题?
why?
因為前者,「123」是在Func函數的內部,也就是函數的堆疊上,出了函數就沒有了。
而後者「123」是在main函數的內部Func函數執行完了,控制流程回到了main函數還在。
const引用會提高臨時變數的生命週期是指,臨時變數的生命週期本來只是創建該臨時變數的表達式,表達式結束後,被析構,const引用將其生命週期提升到該函數結束時(如果是全域const引用變量,那自然就是提升到整個程式的生命週期),函數結束被析構,而不會將其生命週期提升到函數外部,函數結束時,也會被析構掉的。
const引用其實和右值引用差不多,都是將臨時變數的生命週期從這個表達式提升到函數。
補充一點參考資料
第一段程式main方法:
改為:
const string s = Func();
傳回函數內定義的局部變數是未定義行為。
你這裡const是不會提升局部變數的生命週期的,局部變數是存放在棧上,函數回傳的時候對應的棧會被釋放,也就是局部變數也會被銷毀。你第一個程式不是局部變數宣告週期的問題,const是代表不能修改的意思,但是你的s變數沒有用const修飾,所以不能賦值。
個人覺得,上面的回答都有些問題。 。 。
看題主的代碼:
這段程式碼確實會報錯,但是只要把
const string& Func()
中的&
去掉就可以了。出錯的原因並不是"123"在棧中,當函數返回時出棧導致的錯誤。而是,"123"本身是在靜態資料區的,當函數返回時實際返回的是"123"在靜態資料區的地址,該地址在函數Func中是局部變數(在堆疊中),此時,我們使用引用類型傳回該局部變數的(但是,會發生出棧操作),我們的參考變數被釋放了,就會出錯。但是,如果我們不使用&
,返回的時候我們實際上得到的是地址值的中間變數(函數的非引用返回值都會保存在中間變數中),此時堆疊操作是不影響我們取得正確的地址值的。