智能指针 + 周期 + "->"
Smart pointers + cycles + "->"
有时我真的很确定我想要指针的循环依赖性,并且循环上的每个对象都应该能够使用他的指针(所以它不能是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_ptr
或unique_ptr
来自动管理节点的寿命。节点本身可以用weak_ptr
、observer_ptr
或引用(Node&(来相互引用
- EASTL矢量<向量<int>>连续的
- Pisano 周期生成器在 3 位周期内行为不正确
- 如何在共享库的整个生命周期内存储数据
- 提升图形库:资源受限的最短周期
- 我必须找到给定数组中所有数字的周期,就像有很多解决方案,但数组的大小是 10^5
- 如何理解句子的生命周期始于对e的评估
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了
- 找到包括特定边的最短周期
- Go/C++gRPC客户端通道和存根生命周期
- 如何将"this"的生命周期移动到C++中的另一个对象中?
- 是否可以通过使用移动/交换 c++11 来延长返回的临时变量的生命周期
- 如何在没有同步的情况下使用多个线程(2、4,8、16 个线程)在循环(10,100、1000 个周期)中打印字符串?
- C/C++ 经过的流程周期,不包括断点处
- 标准::计时::时钟、硬件时钟和周期计数
- 使用对象的生命周期作为设置器的安全性
- time_t的时钟周期和获取时间问题
- 查询时间/周期是针对所有内核/线程的序列化请求还是并行请求?
- 临时人员的生命周期传递给函数
- 使用贝尔曼福特检测产品超过阈值的周期
- 为什么这个循环每次迭代需要 1.32 个周期