簡體   English   中英

從函數返回const對局部變量的引用

[英]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
}

我的問題是=>

  1. getA1()的實現是否正確? 我覺得這是不正確的,因為它返回局部變量的地址或臨時變量。

  2. main (1,2,3)中哪些語句會導致未定義的行為?

  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM