boost、共享 ptr 与弱 ptr?什么时候使用哪个? [重复]

问题描述 投票:0回答:4

在我当前的项目中,我广泛使用

boost::shared_ptr

最近我的队友也开始使用

weak_ptr
。我不知道该使用哪一个以及何时使用。

除此之外,如果我想将

weak_ptr
转换为
shared_ptr
,我该怎么办。在
weak_ptr
上加锁来创建
shared_ptr
会影响我在其他线程中的代码吗?

c++ memory-management boost shared-ptr weak-ptr
4个回答
71
投票

总体而言,

强指针保证其自身的有效性。例如,在以下情况下使用它们:

  • 您拥有被指向的物体;你创造它并摧毁它
  • 如果对象不存在,则没有定义的行为
  • 您需要强制该对象存在。

弱指针保证知道其自身的有效性。例如,在以下情况下使用它们:

  • 您可以访问它,但它不是您的。
  • 如果对象不存在,您已定义行为

弱指针上的Lock()返回强指针;这就是访问弱指针的方式。如果该对象不再有效(已被删除等),则强指针将为 NULL,否则,它将指向该对象。您需要检查一下。

以这种方式设置,以便您在使用对象时不会意外删除该对象,因为您已经创建了一个临时(本地)强指针,因此在该强指针保留的同时保证了该对象的存在。当您使用完该对象后,通常会让强指针超出范围(或重新分配它),然后允许删除该对象。对于多线程,请像对待其他没有内置线程安全性的东西一样小心地对待它们,请注意,我上面提到的保证在多线程时会保持不变。 AFAIK 除此之外他们没有做任何特别的事情。 boost 共享指针还具有类似垃圾收集器的功能,因为当指向对象的最后一个强指针消失或指向其他位置时,该对象将被删除。

还有其他答案中提到的性能和循环依赖。

从根本上来说,我想说的是,boost 共享指针库可以让你在编写程序时不会搞砸,但它不能替代花时间正确设计你的指针、对象所有权和生命周期。如果您有这样的设计,您可以使用该库来强制执行它。如果您没有这样的设计,您可能会遇到与以前不同的问题。


23
投票
weak_ptr

,即

shared_ptr
指向一个对象,而
shared_ptr
返回到您自己。这是因为
shared_ptr
无法处理循环引用 - 当两个对象超出范围时,相互引用意味着它们没有被“垃圾收集”,因此内存丢失并且出现内存泄漏。由于
weak_ptr
不会增加引用计数,因此不会出现循环引用问题。一般来说,这也意味着,如果您只想获取指向引用计数的对象的指针,并且不想增加其引用计数,那么请使用
weak_ptr

否则,您可以使用

shared_ptr


有关更多信息,请查看 Boost

文档


7
投票

使用弱指针有两个原因:

消除引用计数增加/减少的成本;但是你不应该这样做,因为它很容易出错并且并不能真正节省太多时间
  1. 在簿记数据结构中,例如您有所有“活动”对象 Foo 的索引,即在其他地方使用的对象,并且如果所有“实际”使用都已结束,您不希望在索引中保留 Foo 活动。这是弱指针的基本实际用例。当然还有其他的。
  2. 所以一般来说,我的建议是仅当您知道要删除引用的对象并希望检测到这一点时才使用弱指针。在其他情况下,使用共享指针(引用计数)或直接指针,尤其是。当您知道对象不会被删除时,在方法局部变量中。虽然也容易出错,但比共享指针更快。

注意循环对象不需要弱指针,您可以在大多数正确构造的程序中使用未经处理的常规指针。不过,弱指针风险较小。


-10
投票

© www.soinside.com 2019 - 2024. All rights reserved.