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

发布于 2024-08-17 04:59:22 字数 262 浏览 2 评论 0原文

在我当前的项目中,我非常广泛地使用 boost::shared_ptr

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

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

In my current project I am using boost::shared_ptr quite extensively.

Recently my fellow team mates have also started using weak_ptr. I don't know which one to use and when.

Apart from this, what should I do if I want to convert weak_ptr to shared_ptr. Does putting a lock on weak_ptr to create a shared_ptr affect my code in other thread?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

墨落画卷 2024-08-24 04:59:22

总而言之,

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

  • 您拥有所指向的对象;您创建它并销毁它
  • 如果对象不存在,则没有定义的行为
  • 您需要强制该对象存在。

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

  • 您访问它,但它不属于您。
  • 如果对象不存在,您已经定义了

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

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

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

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

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

In general and summary,

Strong pointers guarantee their own validity. Use them, for example, when:

  • You own the object being pointed at; you create it and destroy it
  • You do not have defined behavior if the object doesn't exist
  • You need to enforce that the object exists.

Weak pointers guarantee knowing their own validity. Use them, for example, when:

  • You access it, but it's not yours.
  • You have defined behavior if the object doesn't exist

Lock() on a weak pointer returns a strong pointer; this is how you access the weak pointer. If the object is no longer valid (it's been deleted, etc), then the strong pointer will be NULL, otherwise, it will point at the object. You will need to check this.

It's set up this way so that you cannot accidentally delete the object while you're using it, because you've made a temporary (local) strong pointer, and thus garunteed the object's existence while that strong pointer remains. When you're done using the object, you generally let the strong pointer fall out of scope (or reassigning it), which then allows the object to be deleted. For multithreading, treat them with same care you treat other things that don't have built-in thread safety, noting that the guarantee I mentioned above will hold when multithreading. AFAIK they don't do anything special past that.

The boost shared pointers also have garbage-collector like features, since when the last strong pointer to an object goes away or points somewhere else, the object gets deleted.

There's also the performance and circular dependencies mentioned in the other answers.

Fundamentally, I would say that the boost shared pointer library allows you to not mess up putting together a program, but it is no substitute for taking the time to properly design your pointers, object ownerships and lifetimes. If you have such a design, you can use the library to enforce it. If you don't have such a design, you're likely to run into different problems than before.

多孤肩上扛 2024-08-24 04:59:22

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

否则,您可以使用shared_ptr

有关详细信息,请查看 Boost 文档

Use weak_ptr when the objects you create contain cyclical references, i.e. shared_ptr to an object with a shared_ptr back to yourself. This is because shared_ptr cannot handle cyclical references - when both objects go out of scope, the mutual referencing means that they are not "garbage collected", so the memory is lost and you have a memory leak. Since weak_ptr does not increase the reference count, the cyclical reference problem does not occur. This also means in general that if you just want to take a pointer to something that is reference counted and do not want to increase its reference count, then use weak_ptr.

Otherwise, you can use shared_ptr.

For more information, check the Boost documentation.

z祗昰~ 2024-08-24 04:59:22

共享指针实现引用计数,弱指针不会影响引用计数,如果您没有指向对象的共享指针,只有弱指针,则该对象将被删除,并且弱指针现在会告诉您该对象已丢失。

使用弱指针有两个原因:

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

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

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

Shared pointers implement reference counting, weak pointers do not affect reference counting and if you don't have shared pointers to an object, only weak pointers, the object gets deleted and the weak pointers now tell you that the object has been lost.

There are two reasons to use a weak pointer:

  1. To eliminate the cost of reference count increase / decrease; however you shouldn't do this because it is error-prone and doesn't really save much time
  2. In bookkeeping data structures, e.g. you have an index of all objects Foo that are "alive", i.e. used somewhere else, and you don't want to keep a Foo alive in the index if all the "real" uses have ended. This is the basic realistic use case for weak pointers. Of course others exist also.

So in general, my recommendation would be to use weak pointers only when you know that you want to let the referenced objects be deleted and want to detect that. In other cases use shared pointers (reference counting), or direct pointers, esp. in method local variables when you know that the objects are not going to get deleted. Also errorprone, though, but faster than shared pointers.

N.B. cyclical objects do not need weak pointers, you can use non-cooked, regular pointers instead in most properly constructed programs. Weak pointers less risky, though.

糖粟与秋泊 2024-08-24 04:59:22

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

You should probably not be trying to use weak pointers at all unless you are trying to implement a garbage collector, which is not a hot idea in C++ because it's too hard to keep track of everything that could go wrong closely enough.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文