让我重复你的问题:“我的问题,循环数据结构如何使引用计数高于零,请在 C++ 程序中举例说明。请weak_ptrs 再次举例说明问题是如何解决的。”
这样的 C++ 代码会出现问题(从概念上讲):
class A { shared_ptr<B> b; ... };
class B { shared_ptr<A> a; ... };
shared_ptr<A> x(new A); // +1
x->b = new B; // +1
x->b->a = x; // +1
// Ref count of 'x' is 2.
// Ref count of 'x->b' is 1.
// When 'x' leaves the scope, there will be a memory leak:
// 2 is decremented to 1, and so both ref counts will be 1.
// (Memory is deallocated only when ref count drops to 0)
回答您问题的第二部分:引用计数在数学上不可能处理循环。因此,weak_ptr(基本上只是shared_ptr 的精简版)不能用于解决循环问题——程序员正在解决循环问题。
为了解决这个问题,程序员需要知道对象之间的所有权关系,或者如果没有这种所有权自然存在,则需要发明一种所有权关系。
上面的C++代码可以改成A拥有B:
class A { shared_ptr<B> b; ... };
class B { weak_ptr<A> a; ... };
shared_ptr<A> x(new A); // +1
x->b = new B; // +1
x->b->a = x; // No +1 here
// Ref count of 'x' is 1.
// Ref count of 'x->b' is 1.
// When 'x' leaves the scope, its ref count will drop to 0.
// While destroying it, ref count of 'x->b' will drop to 0.
// So both A and B will be deallocated.
一个关键的问题是:weak_ptr可以在程序员因为缺乏权限或信息不足而无法分辨所有权关系并且无法建立任何静态所有权的情况下使用吗?
答案是:如果对象之间的所有权不明确,weak_ptr无法提供帮助。如果有一个循环,程序员必须找到它并打破它。另一种补救措施是使用具有完整垃圾收集的编程语言(例如:Java、C#、Go、Haskell),或使用与 C/C++ 一起使用的保守(=不完美)垃圾收集器(例如:Boehm GC) .