天天看點

關于C++中的函數傳回局部string的問題

函數傳回局部變量string的時候能不能被引用?

前兩天被同僚突然問道這個問題,見到string一時糊塗了,最初學習C++的時候,就說不能引用局部變量,現在怎麼糊塗了呢?呵呵

今天想了下,原來是被函數外表蒙蔽了,看個例子

std::string TestStringReference()
{
    std::string strTest = "This is a test.";
    return strTest;
}

int main()
{
    std::string& strRefer = TestStringReference();
    std::cout << "strRefer:" << strRefer << std::endl;
    return 0;
}
           

這裡的std::string& strRefer = TestStringReference();是正确的嗎?

咋一看,這裡不是引用了函數傳回的局部對象嗎? 适用課本的結論:不正确的!

經過測試,上面的用法沒有任何問題,程式不會core,編譯器也沒有任何告警或錯誤,編譯器絕對是沒有問題的,肯定是自己的問題。

調試了下,發現TestStringReference函數在return前,都會調用string的構造函數,這裡沒有需要再構造的對象呀?!

想了一下,恍然大悟:是否引用局部對象(本例僅對基本類型和string,不包括指針類的),取決于函數的傳回值,而不是指派語句。

即這種函數定義才是傳回局部對象的引用

std::string& TestStringReference()
{
    std::string strTest = "This is a test.";
    return strTest;
}
           

這樣就不對了,編譯器直接會告警:warning C4172: 傳回局部變量或臨時變量的位址

第一種定義的方法,實際上傳回的不是局部變量,而是編譯器新構造的臨時對象,現在編譯器都支援RVO(Return Value Optimization),會把這些臨時對象,賦給需要新構造的對象上,無需再次構造。

這裡的問題實際上是個概念混淆了,導緻了不确定。把string換成int等基本類型也是一樣的。

是以,請明确什麼是傳回局部變量引用!