2013-04-24 74 views
2

從升壓:: shared_ptr的Boost文檔:boost shared_ptr騎行參考?

由於實現使用引用計數, shared_ptr實例週期不會被回收。例如,如果main() 將shared_ptr持有給A,而A直接或間接持有 shared_ptr返回給A,則A的使用計數將爲2.破壞 原始shared_ptr將使A掛起,使用計數爲1。使用 weak_ptr來「中斷循環」。

我不明白這一段,你能否提供一個這種情況的最小例子並解釋結果。

回答

4

如何智能指針的工作?他們記住指向該對象的智能指針的count,當新的共享指針控制對象時增加這個count,並且如果共享指針失去對該對象的控制,則減少count

假設你有一個類:

class A{ 
public: 
    A(){std::cout << "Object created" << std::endl;} 
    ~A(){std::cout << "Object destroyed" << std::endl;} 
    void setSibling(boost::shared_ptr<A> &sibling){ 
     m_sibling = sibling; 
    } 
private: 
    boots::shared_ptr<A> m_sibling;  
}; 

和一個Foo():

void foo(){ 
    //count increases from 0 to 1 (ptr take control on instance of A) 
    boost::shared_ptr<A> ptr(new A); 

    //count increases from 1 to 2 (m_sibling take control on instanse of A) 
    ptr->setSibling(ptr); 

    //count decreases from 2 to 1 
    //(ptr is destroyed and lose control on instance of A) 
    return; 
} 

的m_sibling將失去控制時〜A()會被調用,但是〜A()只有當所有共享指針失去控制時纔會被調用。 所以在foo被調用後,你不能訪問A的那個實例,但count是1,並且共享指針不會刪除那個對象,所以你有內存和資源泄漏。

請參閱weak_ptr的文檔以瞭解如何在shared_ptr中使用它們。

總之:弱指針就像共享指針,但不會增加count。如果您有一個從shared_ptr創建的weak_ptr實例到銷燬的對象,那麼如果您嘗試訪問原始指針,則weak_prt實例將拋出異常(segfault不會發生)。 boost文檔中有一個示例,如何使用weak_ptr::lock()方法正確使用weak_prt

+0

不要忘記[enable_shared_from_this](http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/enable_shared_from_this.html)!! – Trompa 2013-04-24 07:31:29

0

下面是一個例子(注意:~A從不這裏叫做):

#include <boost/shared_ptr.hpp> 
#include <iostream> 

using boost::shared_ptr; 
struct A 
{ 
    ~A() 
    { 
     std::cout << "~A()" << std::endl; 
    } 
    void set_shared_ptr(const shared_ptr<A> &p) 
    { 
     p_ = p; 
    } 
    shared_ptr<A> p_; 
}; 

int main() 
{ 
    shared_ptr<A> q(new A); 
    q->set_shared_ptr(q); 
    q.reset(); 
} 
1

想象一下寶藏。
你的朋友需要胸部並放入一些黃金。而且他還製作了一張地圖。
它是一個帶有一個條款的神奇地圖:如果您刻錄地圖的最新副本,那麼寶藏和黃金已經消失。
你的朋友把地圖放在胸部正上方,爲你製作第二張地圖,並用裏面的第一張地圖關閉胸部。
他給你地圖的第二個副本,隨着寶藏消失。
問題是:如果你刻錄地圖會發生什麼?
答案:沒什麼,寶藏還在某處。

爲什麼?因爲地圖的最新副本仍在胸前!

-1

Boost documentation

由於實現使用引用計數, shared_ptr實例的週期將不被回收。

你寫:

我無法理解這一段

這是很好的;那是因爲你很聰明。該段沒有任何意義。如果你認爲你明白了,那就意味着你沒有。

由於存在週期性依賴關係,因此不能回收週期,因此需要在循環的其餘部分被回收之前,循環中的任何部分都不能回收,因此必須在銷燬開始之前將每個對象都銷燬。如果您有循環依賴關係,那麼這是程序的破碎設計的一部分。不要試圖指責智能指針(或引用計數)。

基本依賴性問題的任何部分都不以任何方式與智能指針的實現細節相關; 它是由擁有智能指針的非常定義引起的:擁有的對象在(最後一個)擁有指針的析構函數開始運行之前不會被銷燬。

當然,對於獨家所有權智能指針如std::unique_ptr也是如此,甚至沒有引用計數!

使用weak_ptr來「斷開循環」。

不要。避免週期。你不能「打破」一個循環。沒有像「打破」一個循環這樣的事情。

Boost的文檔在這裏比無用的更糟糕。這很危險。它將不變和實現混合在一個層次上,這表明對智能指針語義的理解很差。

它講述了很多關於假信息和反模式重現自己的能力!