我问了几个关于内存管理的问题(here和here),并且总有人建议我使用boost :: shared_ptrs。
鉴于它们看起来有多么有用,我正在认真考虑切换整个应用程序以使用boost :: shared_ptrs。
然而,在我用双脚跳进去做之前,我想问一下 - 有没有人对boost :: shared_ptrs有任何不好的经历?使用它们是否有一些陷阱需要注意?
现在,它们看起来好得令人难以置信 - 自动处理我的大部分垃圾收集问题。有什么缺点?
答案 0 :(得分:4)
缺点是它们不是免费的。当shared_ptr
/ shared_array
(或普通旧堆栈分配)执行时,您尤其不应使用scoped_ptr
/ scoped_array
。如果有的话,你需要用weak_ptr
手动打破周期。你链接到的矢量问题是我可以找到shared_ptr
的一个案例,第二个问题我不会。不复制是一种过早的优化,特别是如果字符串类已经为你做了。如果对字符串类进行引用计数,它也可以正确实现COW,而使用shared_ptr<string>
方法无法实现。使用shared_ptr
willy-nilly也会引入与外部库/ apis的“界面摩擦”。
答案 1 :(得分:2)
在C ++中使用Boost共享指针或任何其他内存管理技术并不是灵丹妙药。没有替代仔细编码。如果您深入使用boost :: shared_ptr,请注意对象所有权并避免循环引用。您将需要显式中断循环或在必要时使用boost :: weak_ptr。
另外要小心,从分配时起始终将boost :: shared_ptr用于实例。这样你就可以肯定你不会有悬空引用。确保这种方法的一种方法是使用在shared_ptr中返回新创建的对象的工厂方法。
typedef boost::shared_ptr<Widget> WidgetPtr;
WidgetPtr myWidget = Widget::Create();
答案 2 :(得分: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有一个侵入式指针类型(或者更确切地说,可能有,但我自己也没有听说过。)
答案 3 :(得分:0)
动态内存开销(即额外分配)加上与引用计数智能指针相关的所有开销。