我已经读过,weak_pointers可以用来打破循环引用。
考虑下面的循环引用示例
struct A
{
boost::shared_ptr<A> shrd_ptr;
};
boost::shared_ptr<A> ptr_A(boost::make_shared<A>());
boost::shared_ptr<A> ptr_b(boost::make_shared<A>());
ptr_A->shrd_ptr = ptr_b;
ptr_b->shrd_ptr = ptr_A;
现在上面是一个循环引用的例子,我想知道如何打破
上面的循环引用是使用weak_ptr
?
更新: 根据收到的建议,我想出了以下内容:
struct A
{
boost::weak_ptr<A> wk_ptr;
};
boost::shared_ptr<A> ptr_A (boost::make_shared<A>());
boost::shared_ptr<A> ptr_B (boost::make_shared<A>());
ptr_A->wk_ptr = ptr_B;
ptr_B->wk_ptr = ptr_A;
这是正确的方法吗?
答案 0 :(得分:34)
循环引用的经典示例是您有两个类A
和B
,其中A
引用了B
,其中引用了A
}:
#include <memory>
#include <iostream>
struct B;
struct A {
std::shared_ptr<B> b;
~A() { std::cout << "~A()\n"; }
};
struct B {
std::shared_ptr<A> a;
~B() { std::cout << "~B()\n"; }
};
void useAnB() {
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->b = b;
b->a = a;
}
int main() {
useAnB();
std::cout << "Finished using A and B\n";
}
如果两个引用均为shared_ptr
,则表示A
拥有B
,B
拥有A
,这应该会响起警钟。换句话说,A
让B
保持活跃,B
让A
保持活跃。
在此示例中,实例a
和b
仅用于useAnB()
函数,因此我们希望它们在函数结束时被销毁,但正如我们在运行时所看到的那样该程序不会调用析构函数。
解决方案是决定谁拥有谁。假设A
拥有B
但B
不拥有A
,那么我们将A
中的B
引用替换为weak_ptr
像这样:
struct B {
std::weak_ptr<A> a;
~B() { std::cout << "~B()\n"; }
};
然后,如果我们运行该程序,我们会发现a
和b
已按预期销毁。
编辑:在您的情况下,您建议的方法看起来完全有效。取消A
的所有权以及其他拥有A
的内容。