[英]Returning const reference to local variable from a function
我有一些關於從函數返回對局部變量的引用的問題:
class A {
public:
A(int xx)
: x(xx)
{
printf("A::A()\n");
}
};
const A& getA1()
{
A a(5);
return a;
}
A& getA2()
{
A a(5);
return a;
}
A getA3()
{
A a(5);
return a;
}
int main()
{
const A& newA1 = getA1(); //1
A& newA2 = getA2(); //2
A& newA3 = getA3(); //3
}
我的問題是=>
getA1()
的實現是否正確? 我覺得這是不正確的,因為它返回局部變量的地址或臨時變量。
main
(1,2,3)中哪些語句會導致未定義的行為?
在const A& newA1 = getA1();
標准是否保證const引用的臨時綁定在引用超出范圍之前不會被銷毀?
1.
getA1()
實現是否正確? 我覺得這是不正確的,因為它返回本地變量或臨時的地址。
你的程序中getA3()
正確的getAx()
版本是getA3()
。 無論你以后如何使用它們,其他兩個都有不確定的行為。
2.主要(1,2,3)中的哪些陳述會導致未定義的行為?
從某種意義上說,沒有一個。 對於1和2,未定義的行為是函數體的結果。 對於最后一行, newA3
應該是編譯錯誤,因為您不能將臨時綁定到非const引用。
3.在
const A& newA1 = getA1();
標准保證在引用超出范圍之前,不會銷毀由const
引用臨時綁定的內容嗎?
不。以下是一個例子:
A const & newConstA3 = getA3 ();
這里, getA3()
返回一個臨時值,該臨時值的生命周期現在綁定到對象newConstA3
。 換句話說,臨時將存在,直到newConstA3
超出范圍。
Q1:是的,這是一個問題,請參閱Q2的回答。
Q2:1和2是未定義的,因為它們引用了getA1和getA2堆棧上的局部變量。 這些變量超出范圍並且不再可用,並且隨着堆棧不斷變化,可能會覆蓋更糟糕的變量。 getA3起作用,因為創建了返回值的副本並將其返回給調用者。
問題3:對於Q2的回答,沒有這樣的保證。
我認為主要的問題是你根本不回歸臨時工,你應該這樣做
return A(5);
而不是
A a(5);
return a;
否則,您將返回本地變量地址,而不是臨時變量。 而臨時的const引用僅適用於臨時工。
我認為它在這里解釋: 臨時到const引用
如果您將在VC6上編譯它,您將收到此警告
******編譯器警告(級別1)C4172返回局部變量或臨時的地址函數返回局部變量或臨時對象的地址。 函數返回時會破壞局部變量和臨時對象,因此返回的地址無效。
在測試這個問題時,我發現有趣的事情(給定的代碼在VC6中工作):
class MyClass
{
public:
MyClass()
{
objID=++cntr;
}
MyClass& myFunc()
{
MyClass obj;
return obj;
}
int objID;
static int cntr;
};
int MyClass::cntr;
main()
{
MyClass tseadf;
cout<<(tseadf.myFunc()).objID<<endl;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.