45

在我目前的项目中,我使用boost::shared_ptr得相当广泛。

最近我的队友也开始使用weak_ptr. 我不知道该使用哪一个以及何时使用。

除此之外,如果我想转换weak_ptrshared_ptr. 锁定weak_ptr以创建shared_ptr会影响我在其他线程中的代码吗?

4

4 回答 4

70

总的来说和总结,

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

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

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

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

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

它是这样设置的,因此您在使用它时不会意外删除该对象,因为您已经创建了一个临时(本地)强指针,因此在该强指针保留时保证了该对象的存在。当您使用完对象后,通常会让强指针超出范围(或重新分配它),然后允许删除该对象。对于多线程,请像对待其他没有内置线程安全的东西一样小心对待它们,注意我上面提到的保证在多线程时成立。AFAIK 过去他们没有做任何特别的事情。

boost 共享指针还具有类似垃圾收集器的功能,因为当指向对象的最后一个强指针消失或指向其他地方时,该对象将被删除。

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

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

于 2010-01-10T06:07:53.630 回答
23

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

否则,您可以使用shared_ptr.

有关更多信息,请查看 Boost文档

于 2010-01-10T05:37:54.377 回答
6

共享指针实现引用计数,弱指针不影响引用计数,如果你没有指向对象的共享指针,只有弱指针,对象被删除,弱指针现在告诉你对象已经丢失。

使用弱指针有两个原因:

  1. 消除引用计数增加/减少的成本;但是您不应该这样做,因为它容易出错并且不会真正节省很多时间
  2. 在簿记数据结构中,例如,您拥有所有“活动”对象 Foo 的索引,即在其他地方使用过,如果所有“真实”使用都已结束,您不希望 Foo 在索引中保持活动状态。这是弱指针的基本实际用例。当然其他的也存在。

所以一般来说,我的建议是只有当你知道你想让被引用的对象被删除并想要检测到它时才使用弱指针。在其他情况下,使用共享指针(引用计数)或直接指针,尤其是。当您知道对象不会被删除时,在方法局部变量中。虽然也容易出错,但比共享指针快。

NB 循环对象不需要弱指针,您可以在大多数正确构造的程序中使用非熟化的常规指针。不过,弱指针风险较小。

于 2010-01-10T05:38:10.413 回答
-10

除非您尝试实现垃圾收集器,否则您可能根本不应该尝试使用弱指针,这在 C++ 中不是一个热门的想法,因为很难足够密切地跟踪可能出错的所有内容。

于 2010-01-10T12:09:48.563 回答