智能指针 + 周期 + "->"

Smart pointers + cycles + "->"

本文关键字:gt 周期 智能 指针      更新时间:2023-10-16

有时我真的很确定我想要指针的循环依赖性,并且循环上的每个对象都应该能够使用他的指针(所以它不能是weak_ptr(。

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

如果我想实现图呢?我可以使用智能指针吗?在图中有循环,但对于weak_ptr,我不能使用"->"。我能做什么?

我读了一些关于StackOverflow的文章、参考资料和主题,但看起来我仍然没有得到智能指针。真的,为什么不存在"->"的weak_ptr变体?

从概念的角度来处理这个问题,而不是从实现的角度。智能指针表示所有权并且智能指针的存在不会使原始指针作为非拥有观察者的角色失效。

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

共享所有权是否适用(例如,顶点只有在至少有一条边连接到它的情况下才存在(?如果是这样,请使用std::shared_ptr来表示所有权,同样使用非所有权观察者的原始指针。如果你需要相互所有权(即所有权循环(,其中"一个顶点只有在一条边指向它的时候才存在,而一条边只有在一个顶点指向它的地方才存在",那么1。仔细检查这样的设计是否正确和可维护,以及2。如果是这样,请在循环中的某个位置使用std::weak_ptr来打破所有权循环。您总是可以lock()weak_ptr来获得shared_ptr

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

您可以在循环中的某个位置使用weak_ptr;您只需要先将weak_ptr提升为shared_ptr,然后才能取消引用它们。您可以通过调用weak_ptr::lock()或简单地将weak_ptr传递给shared_ptr的构造函数来实现这一点(但要注意;如果weak_ptr指向的对象已被销毁,这将引发bad_weak_ptr异常。

如果你真的不能做到这一点(例如,如果循环中涉及的所有对象都是同一类型的,这可能是你的图形示例中的情况(,另一个选项是在链中的某个位置放置一个release函数,使有问题的对象将其所有shared_ptr设置为null。

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

是的,但这只是一个起点。

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

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

shared_ptr-存在许多(或潜在的许多(所有者,最后一个所有者必须处理对象

weak_ptr-可能存在许多所有者,但这不是其中之一,弱指针可能会超过所指向的对象,如果所指向对象被丢弃,则弱指针将为null(即锁定方法将返回null shared_ptr(

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

解决方案是将设计拆分为一个对象,该对象将拥有所有部分和部分(循环节点(。拥有对象可以使用shared_ptrunique_ptr来自动管理节点的寿命。节点本身可以用weak_ptrobserver_ptr或引用(Node&(来相互引用