weak_ptr 与循环引用一起使用
Use of weak_ptr with cyclic references
所以我很难理解为什么我们必须使用 weak_ptr
尤其是循环引用问题,请考虑以下代码:
class B; //forward declaration
class A {
shared_ptr<B> b_ptr;
public:
void set_B(shared_ptr<B>& b)
{
b_ptr = b;
}
A() { cout << "A constructor" << endl; }
~A() { cout << "A destructor" << endl; }
};
class B {
shared_ptr<A> a_ptr;
public:
void set_A(shared_ptr<A>& a)
{
a_ptr = a;
}
B() { cout << "B constructor" << endl; }
~B() { cout << "B destructor" << endl; }
};
int main() {
shared_ptr<A> a = make_shared<A>();
shared_ptr<B> b = make_shared<B>();
a->set_B(b);
b->set_A(a);
}
现在据我所知,当 a
和 b
都超出范围并且它们的引用计数为 0 时,它们会尝试解除分配并销毁指向内存的指针,但在这种情况下它们不能这样做,因为两个指向的对象都有 shared_ptr
的引用计数为 1,这使得它们不可删除,现在是真的吗?
然后,它说要解决这个问题,我必须将 class B
中的 shared_ptr
变成 weak_ptr
,这是为什么呢?它的引用计数仍然为 1,不是吗?即使 weak_ptr 仍然有 shared_ptr<B> b_ptr;
,它的引用计数仍然为 1,那么如何删除它呢?
它还提到 weak_ptr
破坏了强所有权引用,但是 weak_ptr 怎么会 没有所有权,它将如何访问该对象?
提前致谢。
所有std::shared_ptr
,你有:
int main() {
std::shared_ptr<A> a = std::make_shared<A>(); // ref_count_a = 1
std::shared_ptr<B> b = std::make_shared<B>(); // ref_count_b = 1
a->set_B(b); // ref_count_b = 2
b->set_A(a); // ref_count_a = 2
} // ref_count_a = 1 && ref_count_b = 1
// memleak due to the cycle
有
class B {
std::weak_ptr<A> a_ptr;
// ...
};
变成:
int main() {
std::shared_ptr<A> a = std::make_shared<A>(); // ref_count_a = 1
std::shared_ptr<B> b = std::make_shared<B>(); // ref_count_b = 1
a->set_B(b); // ref_count_b = 2
b->set_A(a); // ref_count_a = 1 , weak_ref_a = 1
} // ref_count_a = 0 && ref_count_b = 1
// -> release a -> ref_count_b = 0
// -> release b (+ control block) -> weak_ref_a = 0
// -> release control block of a
Also it mentions that a weak_ptr breaks strong ownership reference but how can a weak_ptr have no ownership, how will it access the object?
控件为shared_ptr
维护一个计数器(释放对象)
和一个 weak_ptr
的计数器来释放控制块。
weak_ptr 检索 shared_ptr 感谢控制块。
Finally I heard that a weak_ptr is a smart pointer which can use methods such as lock() or expired() to manage a shared_ptr, again is this correct?
是
所以我很难理解为什么我们必须使用 weak_ptr
尤其是循环引用问题,请考虑以下代码:
class B; //forward declaration
class A {
shared_ptr<B> b_ptr;
public:
void set_B(shared_ptr<B>& b)
{
b_ptr = b;
}
A() { cout << "A constructor" << endl; }
~A() { cout << "A destructor" << endl; }
};
class B {
shared_ptr<A> a_ptr;
public:
void set_A(shared_ptr<A>& a)
{
a_ptr = a;
}
B() { cout << "B constructor" << endl; }
~B() { cout << "B destructor" << endl; }
};
int main() {
shared_ptr<A> a = make_shared<A>();
shared_ptr<B> b = make_shared<B>();
a->set_B(b);
b->set_A(a);
}
现在据我所知,当 a
和 b
都超出范围并且它们的引用计数为 0 时,它们会尝试解除分配并销毁指向内存的指针,但在这种情况下它们不能这样做,因为两个指向的对象都有 shared_ptr
的引用计数为 1,这使得它们不可删除,现在是真的吗?
然后,它说要解决这个问题,我必须将 class B
中的 shared_ptr
变成 weak_ptr
,这是为什么呢?它的引用计数仍然为 1,不是吗?即使 weak_ptr 仍然有 shared_ptr<B> b_ptr;
,它的引用计数仍然为 1,那么如何删除它呢?
它还提到 weak_ptr
破坏了强所有权引用,但是 weak_ptr 怎么会 没有所有权,它将如何访问该对象?
提前致谢。
所有std::shared_ptr
,你有:
int main() {
std::shared_ptr<A> a = std::make_shared<A>(); // ref_count_a = 1
std::shared_ptr<B> b = std::make_shared<B>(); // ref_count_b = 1
a->set_B(b); // ref_count_b = 2
b->set_A(a); // ref_count_a = 2
} // ref_count_a = 1 && ref_count_b = 1
// memleak due to the cycle
有
class B {
std::weak_ptr<A> a_ptr;
// ...
};
变成:
int main() {
std::shared_ptr<A> a = std::make_shared<A>(); // ref_count_a = 1
std::shared_ptr<B> b = std::make_shared<B>(); // ref_count_b = 1
a->set_B(b); // ref_count_b = 2
b->set_A(a); // ref_count_a = 1 , weak_ref_a = 1
} // ref_count_a = 0 && ref_count_b = 1
// -> release a -> ref_count_b = 0
// -> release b (+ control block) -> weak_ref_a = 0
// -> release control block of a
Also it mentions that a weak_ptr breaks strong ownership reference but how can a weak_ptr have no ownership, how will it access the object?
控件为shared_ptr
维护一个计数器(释放对象)
和一个 weak_ptr
的计数器来释放控制块。
weak_ptr 检索 shared_ptr 感谢控制块。
Finally I heard that a weak_ptr is a smart pointer which can use methods such as lock() or expired() to manage a shared_ptr, again is this correct?
是