C++的智能指针weak_ptr和普通指针的区别

我们之前说过weak_ptr可以用来解决share_ptr循环引用的问题,先来看看循环引用问题

    struct Node {
        std::shared_ptr<Node> next;
    };
    auto node1 = std::make_shared<Node>();
    auto node2 = std::make_shared<Node>();
    node1->next = node2;
    node2->next = node1;  // 循环引用

两个share指针指向的资源中的share指针指向对方,这样析构的时候,两个指针的强引用计数都从2减到1,不为0,资源没有释放

改为weak指针,只引用不计数,不增加share指针中的强引用计数,可以正常释放资源

    struct Node {
        std::weak_ptr<Node> next;
    };
    auto node1 = std::make_shared<Node>();
    auto node2 = std::make_shared<Node>();
    node1->next = node2;
    node2->next = node1;

下面看用普通指针能否解决

    struct Node {
        std::shared_ptr<Node>*next;
    };
    auto node1 = std::make_shared<Node>();
    auto node2 = std::make_shared<Node>();
    node1->next = &node2;
    node2->next = &node1;

用普通指针确实没有增加share指针的强引用计数,表面上看似解决了循环引用问题,实际上带来了普通指针的内存安全问题

此外weak_ptr可以通过lock()获取一个share_ptr,通过expired()获知资源是否还在,另外weak指针会进行弱引用计数

每个资源会对应一个控制块,在make_share指针的时候会给资源分配一个控制块,即所有指向同一对象的shared_ptrweak_ptr共享同一个控制块

+----------------------+
|     控制块结构        |
|----------------------|
| 强引用计数 (shared)   | ← 记录有多少个shared_ptr指向该对象
| 弱引用计数 (weak)     | ← 记录有多少个weak_ptr依赖此控制块
| 原始指针              | ← 实际管理的对象指针
| 删除器 (deleter)      | ← 自定义删除函数(如果有)
| 分配器 (allocator)    | ← 自定义分配器(如果有)
+----------------------+

强引用计数用于管理资源,计数为0时释放资源

弱引用计数用于管理控制块,当强引用计数和弱引用计数均为0时释放控制块

控制块在资源释放时仍然存在是为了方便weak_ptr查询资源状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员萌芽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值