2010-02-27 41 views
2

在shared_ptr智能指針中,使用引用計數。但是,引用計數存在一個問題,即它無法打破引用的循環。在C++智能指針中使用循環的引用計數

我對這個問題有四個問題。

1)任何人都可以給我一個參考週期發生的片段嗎? 2)如果不能打破參考週期,RCSP如何保證成功資源管理?有沒有辦法打破第三方產品的週期?

3)是否有避免參考循環?

4)其他智能指針如何?他們如何處理源代碼管理?例如,share_ptr,scope_ptr?

非常感謝!

回答

9

通常避免循環的方法是在循環的任意一點使用弱引用。 shared_ptr有一個伴侶型,weak_ptr,它是專爲此目的而設計的。

減弱的哪個部分是設計問題。在「父母」對象擁有「孩子」的設計中,父母對孩子的引用應該很強(shared_ptr),並且從孩子回到父母的引用應該很弱(weak_ptr)。

5

涉及循環的實際應用是很多種圖表。一個平凡的片段(儘管這是不太可能在現實生活中發生的)會是這樣的:

struct node { 
    node *next; 
}; 

int create_cycle() { 
    node *a = new node; 
    a.next = a; 
} 

create_cycle返回後,我們只分配節點中包含對自身的引用,但有沒有其他的點,所以即使它是垃圾,引用計數器也不會收集它。

Chris Jester-Young已經從實際的角度處理了智能指針的週期性破壞。儘管他沒有詳細討論內部工作原理。

weak_ptr是一種雙向間接指針。即weak_ptr不直接給對象一個acces。相反,要訪問該對象,必須將weak_ptr轉換爲shared_ptr,然後使用該對象來獲取對象 - 但只有仍然存在至少一個其他shared_ptr才能將weak_ptr轉換爲shared_ptr的嘗試才能成功被管理的對象(所以對象有一個非零引用計數並且仍然存在)。

因此,只要weak_ptr存在,你就可以訪問一個對象,但是「知道」對象何時不存在,並且不允許你訪問對象用來存儲(現在已釋放)的內存如果物體已被破壞。

避免週期取決於你正在使用的東西的種類。如果你處理很多圖形(舉一個例子),它們往往幾乎不可能避免,因爲你建模的很多東西都有循環。否則,好吧......這取決於。我猜想有相當數量的開發人員在整個職業生涯中都沒有創建一個包含循環的鏈接結構。其他人可能在平均一週內多次進行。

就其他智能指針而言,如上所述,weak_ptr類型與shared_ptr一起工作;你可以在不使用weak_ptr的情況下使用shared_ptr,但是在某個時刻你必須將weak_ptr轉換爲shared_ptr,才能真正使用weak_ptr。