C++ 11新特性之week_ptr

std::weak_ptr是C++11中的一个重要智能指针类型,它提供非拥有但可观察的对象访问,用于解决循环引用和内存管理问题。它不增加引用计数,仅在有活跃shared_ptr时有效,有助于编写更安全的程序。
摘要由CSDN通过智能技术生成

概述

        在C++11 标准中,智能指针的引入极大地提升了内存管理的安全性和便利性。除了已经广为人知的shared_ptr和unique_ptr之外,还有一个重要但相对较少被单独提及的智能指针类型——std::weak_ptr。std::weak_ptr是C++ 11引入的一种弱引用智能指针,它不拥有所指向对象的所有权,而是对shared_ptr持有的对象提供一种非拥有但可观察的访问方式。weak_ptr主要用于打破共享所有权循环引用的问题,防止出现内存泄漏。

工作原理

        1、不增加引用计数。

        当创建一个weak_ptr时,它不会增加其所指向的对象的引用计数。这意味着,即使有多个weak_ptr指向同一对象,只要没有对应的shared_ptr存在,该对象仍会在所有shared_ptr释放后被正确销毁。

        2、检查有效性。

        通过调用weak_ptr的lock()成员函数,可以获取一个指向同一对象的shared_ptr。如果此时对象已被删除,则返回的shared_ptr为空。因此,在使用weak_ptr之前通常需要先调用lock()来检查对象是否仍然有效。

        3、不阻止对象析构。

        由于weak_ptr仅提供了对目标对象的弱引用,所以在没有活跃的shared_ptr指向该对象时,对象会被正常回收。

使用案例

        单纯使用shared_ptr有时会产生问题,考虑下面的示例代码。

#include <iostream>
using namespace std;

class A;
class B;

typedef shared_ptr<A> A_Share;
typedef shared_ptr<B> B_Share;

class A
{
public:
    B_Share m_b;
};

class B
{
public:
    A_Share m_a;
};

int main()
{
    A_Share a(new A());
    B_Share b(new B());
    a->m_b = b;
    b->m_a = a;
    return 0;
}

        在上面的示例代码中,a和b相互进行引用。在a和b离开作用域时,a和b的引用计数都是1,内存没有正常释放。解决方法是:将A和B中的任意一个类声明的变量改为week_ptr类型。比如:修改类B后的参考代码如下。

class B
{
public:
    weak_ptr<A> m_a;
};

        修改后,b.m_a = a不会增加A对象的引用计数。因此,a离开作用域时,引用计数为0。B对象的引用计数为2,在a和b离开作用域时,引用计数各减1后也为0,从而被正常释放。

应用场景

        1、打破循环引用。

        在两个或多个具有相互引用关系的对象之间使用shared_ptr时,如果没有弱引用的存在,可能会形成循环引用,导致即使外部不再有任何其他引用,这些对象也无法被垃圾回收。在这种情况下,可以通过将一部分引用改为weak_ptr来解决此问题。

        2、缓存与观察者模式。

        在设计缓存系统或者观察者模式时,某个对象可能需要知道另一个对象的状态变化,但并不希望影响该对象的生命周期。这时,可以使用weak_ptr来跟踪对象,而不增加其引用计数。

总结

        std::weak_ptr作为C++ 11的新特性之一,为了解决循环引用和实现特定设计模式提供了关键工具。理解和熟练运用weak_ptr,有助于编写更加安全且资源高效的C++程序。同时,应当注意在恰当的场景下结合shared_ptr一起使用,以达到最佳效果。

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

希望_睿智

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

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

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

打赏作者

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

抵扣说明:

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

余额充值