2011-10-04 96 views
1

只是一個很小的問題:Codepad.org C++代碼提供了錯誤的結果

你能告訴我這裏的問題this代碼?它應該打印出9但它確實4.8921e-270,但是,當取消註釋第4行時,它也可以正常工作。
我不明白這裏可能有什麼問題。謝謝 !

代碼:

double& foo() { 
    double x = 9; 
    double &y = x; 
    //cout << y << "\n"; 
    return y; 
} 

int main() { 
    cout << foo() << "\n"; 
} 

結果: 4.8921e-270

+1

你期望值'9'被存儲在哪裏? –

+0

使x和y保持靜態。如果他們不是,你不知道從foo()返回的是什麼。 –

+0

@PeteWilson:這裏沒有理由讓'y'變成靜態的。 –

回答

8

這是一個糟糕的想法以引用/指針返回對象在堆棧中。當你離開這個功能時,它們可能會被破壞。請返回它按值:

double foo() { 
    double x = 9; 
    double &y = x; 
    //cout << y << "\n"; 
    return y; 
} 

現在的返回值是複製而不是到很可能不存在了一個對象的引用。

+0

很高興知道,但如果我想避免要複製的返回值呢?我讀過'return'語句創建一個對象的副本,然後將返回值賦給一個變量再次創建一個副本。謝謝 –

+1

我不會擔心這個,因爲'float'通常由4個字節組成,不會受到傷害。對於較大的對象,可以考慮傳遞引用/指針(再次,不要在堆棧上創建它們)。 BTW:指針/引用也是4(或8)字節大。當你「返回」它時,它也被複制。 – Constantinius

+0

這只是一個返回大對象引用的測試。那麼,我怎樣才能返回一個對象的引用? 'void foo(double&)'不是一個選項,因爲我正在實現'operator +'等。我也想避免使用指針。 Ty –

4

您正在返回一個對本地對象的引用,當foo完成時,該對象將不再存在,並且在取消引用時會得到未定義行爲。

0

您返回對局部變量的引用 - 由於foo()返回後局部變量超出範圍,該值不再存在。

所以,你應該要麼只是改變返回類型翻番(強烈推薦),並返回x或(如果你確實想/要返回的引用)使用靜態變量來代替:

double& foo() { 
    static double x = 9; 
    double &y = x; 
    return y; 
} 
+1

由於傢伙顯然不知道他的變量存儲在哪裏,引入靜態值可能不會有幫助:-) –

1
double foo() { 
    double x = 9; 
    double &y = x; 
    //cout << y << "\n"; 
    return y; 
} 

從不是一個好主意,以返回對堆棧上的對象的引用。當你離開該功能時,他們很可能會消失。您可以嘗試按價值返回。

0

我經常常量裁判返回一個類的數據成員:

class BigThing {...}; 

class Foo 
{ 
public: 
    const BigThing & getBT() const { return bt; } // For constant BigThing. 
    BigThing & getBT() { return bt; } // For mutable BigThing. 
private: 
    BigThing bt; 
}; 

這時只要你的Foo實例範圍(你不想給裁判返回一個局部變量),那麼使用其中一個getBT()應該是安全和有效的。