智能指针+周期+“ - >”

时间:2014-05-01 13:35:37

标签: c++ c++11 shared-ptr smart-pointers weak-ptr

有时候我确定我希望循环依赖指针,循环中的每个对象都应该能够使用他的指针(所以它不能是weak_ptr)。

我的问题是:这是否意味着我的设计不好?

如果我想实现图表怎么办?我可以使用智能指针吗?在图表中有循环,但使用weak_ptr我不能使用“ - >”。我该怎么办?

我在StackOverflow上阅读了一些文章,参考和主题,但看起来我仍然没有得到智能指针。真的,为什么不存在一些带有“ - >”的weak_ptr的变体?

3 个答案:

答案 0 :(得分:30)

从概念方面而不是实施方面来解决这个问题。智能指针代表所有权。智能指针的存在并不会使原始指针作为非拥有观察者的角色失效。

每个对象是否都有一个明确定义的所有者(例如,图表拥有其所有顶点和边缘)?如果是这样,使用std::unique_ptr来保持图中的顶点和边,并使用顶点和边内的原始指针来互相引用。

共享所有权是否适用(例如,只要至少有一个边连接到顶点,只存在一个顶点)?如果是这样,请使用std::shared_ptr来表示所有权,同样使用非拥有观察者的原始指针。如果你需要相互所有权(即所有权周期),其中只要一个边引用它就只存在一个顶点,只要一个顶点引用它就只存在一个边,"然后1.仔细检查这样的设计是否正确和可维护,以及2.如果是这样,在周期的某个地方使用std::weak_ptr来打破所有权循环。您始终可以lock() weak_ptr获取shared_ptr

对于您的特定图表方案,我相信"图表所拥有的一切"将是最合乎逻辑的所有权计划;但这取决于你任务的特质。

答案 1 :(得分:4)

你可以在周期的某个地方使用weak_ptr;您只需要将weak_ptr提升为shared_ptr s,然后才能取消引用它们。您可以通过调用weak_ptr::lock()或仅通过将weak_ptr传递给shared_ptr的构造函数来执行此操作(但请注意;如果对象为{{{},则会抛出bad_weak_ptr异常1}}点被摧毁。

如果你真的不能这样做(例如,如果循环中涉及的所有对象属于同一类型,在图例中可能就是这种情况),另一种选择是放置weak_ptr在链中某处导致有问题的对象将其所有release s设置为null。

答案 2 :(得分:1)

  

这是否意味着我的设计不好?

是的,但这是一个起点。

让我们考虑一些可用的智能指针。

unique_ptr - 存在一个负责处置对象的所有者。

shared_ptr - 存在许多(或可能很多)所有者,最后一个必须处置该对象

weak_ptr - 许多所有者可能存在,但这不是其中之一,弱指针可能超出指向的对象,如果指向的对象被处置掉,弱指针将为null(即lock方法将返回null shared_ptr)

observer_ptr (n3840) - 尚未成为标准的一部分,因此如果需要,可以使用C风格的指针(T *)。这些工作非常类似于weak_ptr,但程序员有责任确保在指向的对象被处理后不会取消引用所有观察者。

解决方案是将设计拆分为一个拥有所有碎片和碎片(循环节点)的对象。拥有对象可以使用shared_ptrunique_ptr自动管理节点的生命周期。节点本身可以​​使用weak_ptrobserver_ptr或参考(节点&)来引用彼此