shared_ptr、weak_ptr和循环依赖关系

shared_ptr, weak_ptr and circular dependencies

本文关键字:ptr 依赖 关系 循环 weak shared      更新时间:2023-10-16

我认为我的问题类似于shared_ptr和weak_ptr的差异,但我感兴趣的是看看它们是如何协同工作的,而不是一系列差异。

维基百科关于shared_ptr和weak_ptr的页面指出,weak_pointer可以用来解决循环依赖问题,并给出了一个例子:

std::shared_ptr<int> p1(new int(5));
std::weak_ptr<int> wp1 = p1; //p1 owns the memory.
{
std::shared_ptr<int> p2 = wp1.lock(); //Now p1 and p2 own the memory.
if(p2) //Always check to see if the memory still exists
{ 
//Do something with p2
}
} //p2 is destroyed. Memory is owned by p1.
p1.reset(); //Memory is deleted.
std::shared_ptr<int> p3 = wp1.lock(); //Memory is gone, so we get an empty shared_ptr.
if(p3)
{
//Will not execute this.
}

但是我没有看到循环依赖,所以我不明白weak_pointer是如何解决这个问题的。

我本希望看到一些对象a指向对象b,而b以某种方式指向a(其中weak_ptr填充在有向图的一条边之间以断链)。

这个例子好吗?我的想法不好吗?或者有更好的问题和解决方案的例子吗?

在当前版本的维基百科页面中,该示例旨在演示std::weak_ptr的一般使用,而不是特别消除强循环引用。(循环参考仅在给出示例后才提到。)

该示例显示,尽管wp1的寿命很长,但它并不拥有p1所指向的内存,并且一旦p1被重置,wp1就会正确地检测到该内存的删除。换句话说,当通过弱指针(正确地)访问被删除的对象时,wp1既不干扰动态分配的对象的删除,也不引起未定义的行为。

因为弱指针不会干扰释放,所以它们不仅对避免引用循环很有用,而且对实现存储附加属性或缓存现有对象计算属性的关联数组也很有用。由于此类缓存不会干扰释放,因此它们可以依赖于不再使用时删除的主对象,而无需特定于缓存的驱逐策略。