【问题标题】:Use of weak_ptr with cyclic references将 weak_ptr 与循环引用一起使用
【发布时间】:2020-05-27 16:29:57
【问题描述】:

所以我很难理解为什么我们必须使用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);
}

现在据我所知,当 ab 超出范围并且它们的引用计数为 0 时,它们会尝试释放并销毁指向的内存,但在这种情况下它们不能这样做,因为两个指向的对象都有 shared_ptr 的引用计数为 1,这使得它们无法删除,现在是这样吗?

然后,它说要解决这个问题,我必须将class B 中的shared_ptr 设置为weak_ptr,这是为什么呢?它的引用计数仍然为 1,不是吗?即使使用了weak_ptr,仍然有shared_ptr&lt;B&gt; b_ptr; 的引用计数为1,那么如何删除它呢?

它还提到weak_ptr 破坏了强所有权引用,但是weak_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 真的像did you do any research?
  • @KamilCuk 我做得很好,只是想确定一下,所以我脑子里有一个清晰的图像,为什么要使用它们。

标签: c++ shared-ptr weak-ptr


【解决方案1】:

有了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

它还提到了一个weak_ptr 破坏了强所有权引用,但是一个weak_ptr 怎么可能没有所有权,它将如何访问该对象?

控件为shared_ptr维护一个计数器(释放对象) 和weak_ptr 的计数器以释放控制块。 由于控制块,weak_ptr 检索到 shared_ptr。

最后听说weak_ptr是一个智能指针,可以使用lock()或expired()等方法来管理shared_ptr,对吗?

是的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-15
    • 2011-09-11
    • 2015-01-21
    • 1970-01-01
    • 2014-04-11
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多