2009-02-26 39 views
2

我已經問了一些關於內存管理的問題(herehere),並且總是有人建議我使用boost :: shared_ptrs。是否有任何理由不使用Boost :: shared_ptrs?

鑑於他們似乎有用,我認真考慮切換整個應用程序以使用boost :: shared_ptrs。然而,在我用雙腳跳進去之前,我想問 - 有沒有人有過使用boost :: shared_ptrs的不好經歷?使用它們有什麼缺陷需要注意嗎?

現在,它們看起來幾乎太好了,無法成立 - 自動處理我的大部分垃圾收集問題。缺點是什麼?

回答

4

缺點是它們不是免費的。當scoped_ptr/scoped_array(或普通的舊堆棧分配)將會執行時,您尤其不應使用shared_ptr/shared_array。如果您有任何問題,您需要手動中斷weak_ptr。你鏈接到的矢量問題是我可能達到shared_ptr的一種情況,第二個問題我不會。不復制是一種不成熟的優化,特別是如果字符串類已經爲你做了。如果字符串類是引用計數,它也將能夠正確地實現COW,這不能通過shared_ptr<string>方法完成。使用shared_ptr willy-nilly也將引入與外部庫/ apis的「界面摩擦」。

+0

字符串通常不使用COW。它並不能很好地處理多線程應用程序,因此大多數實現都會再次丟棄它。這意味着字符串副本有點昂貴。 – jalf 2009-02-26 05:40:11

0

動態內存開銷(即額外分配)加上與引用計數智能指針相關的所有開銷。

2

在C++中提升共享指針或任何其他內存管理技術不是萬能的。沒有替代仔細的編碼。如果您深入使用boost :: shared_ptr,請注意對象所有權並避免循環引用。你將需要明確地打破循環或在必要時使用boost :: weak_ptr。

還要小心總是使用boost :: shared_ptr作爲分配時刻的實例。這樣你就可以肯定你不會有懸而未決的引用。您可以確保的一種方法是使用返回您在shared_ptr中新創建的對象的工廠方法。

typedef boost::shared_ptr<Widget> WidgetPtr; 
WidgetPtr myWidget = Widget::Create(); 
1

我經常使用shared_ptr。

由於Shared_ptr是按值複製的,因此可能會產生複製指針值和引用計數兩者的代價,但如果使用boost :: intrusive_ptr,則引用計數必須添加到您的類中,並且存在沒有使用原始指針的額外開銷。

但是,根據我的經驗,超過99%的時間,在整個代碼中複製boost :: shared_ptr實例的開銷並不重要。通常,正如C.A.R.Hoare指出的那樣,不成熟的優化是毫無意義的 - 大多數情況下,其他代碼將使用比複製小對象更多的時間。你的旅費可能會改變。如果分析顯示覆制是一個問題,則可以切換到侵入指針。

如前所述,週期必須通過使用weak_ptr來中斷,否則會出現內存泄漏。這將在諸如某些圖形等數據結構中發生,但是,例如,如果您正在製作葉子永遠不會倒退的樹形結構,則可以在樹的節點上使用shared_pointers,而不會出現任何問題。

正確使用shared_ptr可以大大簡化代碼,使其更易於閱讀和維護。在很多情況下使用它們是正確的選擇。

當然,如前所述,在某些情況下,使用scoped_ptr(或scoped_array)是正確的選擇。如果指針不共享,請不要使用共享指針!

最後,最新的C++標準提供了std :: tr1 :: shared_ptr模板,它現在在大多數平臺上,儘管我不認爲tr1有一個入侵指針類型(或者更確切地說, ,但我自己沒有聽說過)。

相關問題