2015-06-16 124 views
12
unique_ptr<A> myFun() 
{ 
    unique_ptr<A> pa(new A()); 
    return pa; 
} 

const A& rA = *myFun(); 

此代碼編譯但rA包含垃圾。有人可以向我解釋爲什麼此代碼無效?解引用臨時unique_ptr

注意:如果在取消引用它之前將myFun的返回值指定給名爲unique_ptr的變量,它將正常工作。

+2

由於您沒有存儲'myFun'返回的'unique_ptr',所以它的析構函數在表達式的末尾被調用,並且它所擁有的對象被釋放。 –

+0

@buttifulbuttefly我看到在組裝中,我不明白如何觸發析構函數調用。 – Kam

+9

[在電視上看到](https://www.youtube.com/watch?v=hEx5DNLWGgA#t=44m2s) –

回答

8

unique_ptr將把所有權轉交給另一個unique_ptr,但是在您的代碼中沒有任何東西可以從返回指針捕獲所有權。換句話說,它不能轉移所有權,所以它會被破壞。 正確的方法是:

unique_ptr<A> rA = myFun(); // Pass the ownership 

const A rA = *myFun(); // Store the values before destruction 

在代碼中,返回指針將被desructed和參考使用該參考所調用指的被很快破壞的對象,在此之後一個未定義的行爲。

5
unique_ptr<A> myFun() 
{ 
    unique_ptr<A> pa(new A()); 
    return pa; 
} 

const A& rA = *myFun(); 

你做了最後一行是什麼:

unique_ptr<A>* temporary = new unique_ptr<A>(nullptr); 
myFun(&temporary); 
const A& rA = *temporary.get(); 
delete temporary; // and free *temporary 

當你刪除temporary它與你它擁有指針和引用內存的合同。所以它破壞了A並釋放了內存。

與此同時,您已經偷偷地將指向該內存的指針作爲對該地址處對象的引用。

你既可以將指針傳遞到本地的unique_ptr:

unique_ptr<A> a = myFun(); 

,或者你可以複製的對象:

A = *myFun().get(); 

的「A」到myFun()暫時的只破壞在關閉聲明,所以它的副本。