2013-08-04 52 views
1

我開始學習shared_ptr和weak_ptr。理論上一切看起來很簡單。但是當我開始測試時,好吧...我有這個非常簡單的程序:shared_ptr.reset()不刪除

​​

問題是,第二個從不刪除。這裏是我的輸出:

Program started 
Main created 
Second created 
Main deleted 
Program ended 

回事請告訴我?我想,如果我重置shared_ptr,並且它的最後一個shared_ptr存在,對象將自動刪除。

+1

這是什麼:'make_shared (*(new Second()));'?您在堆上創建一個對象,然後將其複製到另一個對象。原始的永遠不會被刪除!相反,您應該這樣做:'make_shared ();' –

+0

@ DeX3r您應該使用'make_shared'的參數來初始化其構造函數需要參數的類。 – quamrana

回答

8

您正在初始化您的共享指針錯誤。在使用make_shared時,根本不需要使用new。您傳遞給make_shared的參數將轉發給您正在創建的類的構造函數。

在你的代碼

所以,你make_shared電話應該是這樣的:

shared_ptr<Main> main = make_shared<Main>(); 

shared_ptr<Second> main = make_shared<Second>(); 

相反,你所做的事是通過使用新的泄露版本每個類(中明確而不是刪除它),然後將泄漏值複製到第二個版本中。通過拆分表達爲多行,我們可以更容易地看到你錯做了什麼:

Second *p = new Second; 
shared_ptr<Second> ss = make_shared<Second>(*p); // Calls the Second class copy constructor 
// p is never deleted, so it is leaked. 
+0

那麼我們怎麼也從來沒有看到'make_shared'產生的'Second'實例被破壞? – quamrana

+1

我總是認爲亞洲的程序員......現在不再了:P http://www.youtube.com/watch?feature=player_detailpage&v=V3aLw_9lBDc&t=290 –

+1

@quamrana:既然你沒有重寫'Main'的拷貝構造函數,''第二個'被複制。因此,當泄漏'Main'時,你也會泄漏一個'shared_ptr ':按照設計,不會發生'delete',直到這個參考消失,並且因爲你泄漏了它...... –

2

正如我所說的,情況相當複雜,所以我需要一個模式。

class Main { 
public: 
    shared_ptr<Second> second; 
    Main() 
    { 
     cout << "Main created" << endl; 
     second = make_shared<Second>(*(new Second())); 
    } 
    ~Main() 
    { 
     second.reset(); 
     cout << "Main deleted" << endl; 
    } 
}; 

void fun() 
{ 
    shared_ptr<Main> main = make_shared<Main>(*(new Main())); 
} 

創造main緊接着,我們有:

<anon: Second> (leaked) 

<anon: Main> (leaked) 
      \ 
      |---> <Main.second: Second> 
      /
<main: Main> 

注意main.second<anon>.second如此複製,因爲這些都是shared_ptr<Second>它們都指向的Second同一個實例。

然後,main模具,我們只剩下:

<anon: Second> (leaked) 

<anon: Main> (leaked) ---> <Main.second: Second> (indirectly leaked) 

注意second.reset()不一定破壞指向的對象。它只是重置本地實例shared_ptr如果這是指向該對象的最後一個實例,則該對象將被銷燬,否則......無。

+0

而且我也不需要那個「second.reset();」在主要的析構函數中,對嗎?我的意思是它沒有它,但它是正確的? –

+0

@ DeX3r:正確。 –