[modern c++] std::weak_ptr 问题

std::weak_ptr

It must be converted to std::shared_ptr in order to access the referenced object.

std::weak_ptr is used to track the object, and it is converted to std::shared_ptr to assume temporary ownership.If the original std::shared_ptr is destroyed at this time, 
the object's lifetime is “extended” until the temporary std::shared_ptr is destroyed as well.

Another use for std::weak_ptr is to break reference cycles formed by objects managed by std::shared_ptr. If such cycle is orphaned (i.e., there are no outside shared pointers into the cycle), the shared_ptr reference counts cannot reach zero and the memory is leaked. To prevent this, one of the pointers in the cycle can be made weak.


1. 不能直接访问,必须通过 lock() 成员函数返回一个 std::shared_ptr 后用来访问,这也会引起一次 std::shared_ptr 指向对象的计数增加;
2. 如果std::weak_ptr在通过lock() 获得一个 std::shared_ptr ,那么这会增加一次被管理对象的计数,此时即便原来的 std::shared_ptr 被销毁了,但是由于新创建了一个临时的 std::shared_ptr ,所以也不会触发被管理对象的释放,也就是说会起到 “延长” 生命周期的作用。
   

Demo of resolving reference cycle:

#include <iostream>
#include <memory>
#include <variant>
 
class Node {
    char id;
    std::variant<std::weak_ptr<Node>, std::shared_ptr<Node>> ptr;
  public:
    Node(char id) : id{id} {}
    ~Node() { std::cout << "  '" << id << "' reclaimed\n"; }
    /*...*/
    void assign(std::weak_ptr<Node> p) { ptr = p; }
    void assign(std::shared_ptr<Node> p) { ptr = p; }
};
 
enum class shared { all, some };
 
void test_cyclic_graph(const shared x) {
 
    auto A = std::make_shared<Node>('A');
    auto B = std::make_shared<Node>('B');
    auto C = std::make_shared<Node>('C');
 
    A->assign(B);
    B->assign(C);
 
    if (shared::all == x) {
        C->assign(A);
        std::cout << "All links are shared pointers";
    } else {
        C->assign(std::weak_ptr<Node>(A));
        std::cout << "One link is a weak_ptr";
    }
    /*...*/
    std::cout << "\nLeaving...\n";
}
 
int main() {
    test_cyclic_graph(shared::some);
    test_cyclic_graph(shared::all); // produces a memory leak
}

   
为什么 std::weak_ptr 可以用来解决 reference cycle 问题?
如果 使用 lock() 获得一个临时 std::shared_ptr 后不释放,那么不还是一样存在问题么?

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值