2012-08-25 132 views
0

這是我相信的:得到返回的返回類型是對象的引用嗎?

當一個函數返回它時,創建一個新的臨時對象副本,並且這個臨時對象保留在內存中,從它被調用的地方開始。

當函數返回該對象本身返回的引用時。這意味着該對象不應該是本地的。

所以,當我這樣做:

MyStruct & ReferenceReturn(MyStruct cl) 
{ 
     return cl; 
} 

在main()我做

MyStruct d("notmyname"),g("myname"); 
d = ReferenceReturn(g); 
cout << d.name; 
cout << ReferenceReturn(g).name; 

打印不需要的兩個。

返回什麼? :引用g的本地拷貝,即一旦函數完成就被銷燬,或者在語句結束後對臨時對象的引用被銷燬。但是,既然溫度已經被創造出來,它就會以正確的方式超越。所以我相信它是返回的傳遞值的localcopy的參考。

但是,只要我在結構中進行析構函數,它就完美了,具有以下代碼和特定的輸出。

~MyStruct() 
{ 
    cout << name << " is destroying"; 
    } 

輸出:

myname is destroying 
myname 
myname 
myname is destroying 
.... 

此輸出顯示只有一個對象是爲每一個呼叫建立。 (有兩個電話)

但是,爲什麼它不工作沒有析構函數?

感謝

+0

結果未定義爲這種情況? –

回答

2
MyStruct & ReferenceReturn(MyStruct cl) 
{ 
     return cl; 
} 

創建temporary object,將其分配給cl,返回reference爲對象,銷燬對象。所以,它是dangling reference。編譯器可以使用copy-elision不要複製的對象,但不能...使用的東西LILE

MyStruct & ReferenceReturn(MyStruct& cl) 
{ 
     return cl; 
} 
+0

我發現該對象在聲明後遭到破壞。當我添加析構函數時,它的輸出是在cout << ReferenceResult(g)<< endl;這樣在完成這一行後,對象就會被破壞。 –

+0

@ASHISHNEGI如何在copy-ctor中插入軌跡? http://liveworkspace.org/code/8077039f76b8b4a52d09977b94f31155但在MSVC結果不一樣。所以,這種用法在標準上是不正確的。 – ForEveR

+0

正如你所看到的,在語句「cout」打印「0」之後調用傳入對象的析構函數ouput「d-tor」,這意味着該對象在該語句完成之前是好的。所以它的工作..但是當我刪除析構函數和複製構造函數;垃圾被打印在我的情況。 –

1
MyStruct & ReferenceReturn(MyStruct cl) { 
    return cl; 
} 

是結果未定義這種情況?

該函數表現出未定義的行爲,是的。問題是cl是函數中的本地對象,並且您正在返回對其的引用。這是未定義的行爲。調用者將創建g的副本以傳遞到ReferenceReturn,並且該副本將在return之後被ReferenceReturn函數銷燬,可能在調用方使用該引用之前。

+0

「可能在調用者使用引用之前」沒有析構函數,你是對的;當我正確destuctor別的事情發生 - >本地複製的功能正在越來越被破壞後的cout聲明。所以在這裏做析構函數或者它是不確定的,就像你說的那樣。 –

+0

@ASHISHNEGI:我不知道如何讓它更清晰:函數表現出未定義的行爲。未定義的行爲意味着它看起來可以工作,或者它可能提供不正確的結果或使應用程序崩潰,但在所有情況下它仍然是未定義的行爲。 –