C++之弱引用智能指针weak_ptr的验证

本文详细介绍了C++中智能指针shared_ptr和weak_ptr的使用,特别是它们在解决交叉引用问题中的角色。通过实例展示了如何使用weak_ptr避免内存泄漏,并通过lock函数安全地访问对象。同时,验证了在交叉引用场景下,weak_ptr如何保持引用计数不变并防止循环引用导致的资源无法释放。
摘要由CSDN通过智能技术生成

目录

shared_ptr带来的问题:

标准库weak_ptr弱引用验证:

标准库中weak_ptr交叉引用的验证:


shared_ptr带来的问题:

        在交叉引用时,会造成堆上资源无法释放的问题。

        使用weak_ptr弱引用就可以打破这个交叉引用,因为weak_ptr不改变引用记数。

        但当用weak_ptr指针访问成员方法时,需加 lock 函数,提升为强引用。

        

标准库weak_ptr弱引用验证:

        头文件:#include <memory>

        自定义一个类用:

#include <iostream>
#include <memory>
using namespace std;

class A
{
public:
    A()
    {
        cout << "A的构造" << endl;
    }
    ~A()
    {
        cout << "A的析构" << endl;
    }
    void slots_function()
    {
        cout << "加油,挣大钱" << endl;
    }
};

        主函数:

int main()
{

//    验证弱引用
    //在栈上创建
    shared_ptr<A> ptr1 (new A);
    shared_ptr<A> ptr2 = ptr1;
    cout << ptr2.use_count() << endl;   //>>2

    weak_ptr<A> ptr3 = ptr1;
    cout << ptr2.use_count() << endl;   //>>2
    cout << ptr3.use_count() << endl;   //>>2   ,证明weak_ptr不改变计数
    cout << "----------------------1" << endl;

//    ptr3.slots_function();    //报错
    ptr3.lock()->slots_function();  //弱引用只能通过lock方法调用对象方法
    cout << "----------------------2" << endl;

    cout << ptr3.use_count() << endl;   //2
    cout << ptr3.expired() << endl;     //0     ,作用是判断use_count == 0,返回bool
    cout << "-----------------------3" << endl;

    //析构所有指针
    ptr1.~shared_ptr();
    ptr2.~shared_ptr();
    ptr3.~weak_ptr();
    cout << "---------------------4" << endl;

    cout << ptr3.use_count() << endl;   //0
    cout << ptr3.expired() << endl;     //1
    ptr3.lock()->slots_function();      //当count为零,虽然shared_ptr指向的堆区空间不能用,
    ptr2->slots_function();             //但栈上对象依然存在,shared_ptr的方法还能调用.

    return 0;
}

        运行结果:

        

标准库中weak_ptr交叉引用的验证:

        定义两个可相互引用的类:

#include <iostream>
#include <memory>
using namespace std;

class B;

class A
{
public:
    weak_ptr<B> ptr_b;
public:
    A()
    {
        cout << "A的构造" << endl;
    }
    ~A()
    {
        cout << "A的析构" << endl;
    }
    void slots_function()
    {
        cout << "加油,挣大钱" << endl;
    }
};

class B
{
public:
    weak_ptr<A> ptr_a;
public:
    B()
    {
        cout << "B的构造" << endl;
    }
    ~B()
    {
        cout << "B的析构" << endl;
    }

    //用于升级成强引用,调用别人的方法.
    shared_ptr<A> lock()
    {
        return   (shared_ptr<A>) ptr_a;
    }

    //可以在类中调用交叉对象的方法
    void signals()
    {
        shared_ptr<A> temp = ptr_a.lock();
        if(temp != nullptr)
        {
            temp->slots_function();
        }
    }

};

        主函数:

//    验证交叉引用
    shared_ptr<A> ptr4(new A);
    shared_ptr<B> ptr5(new B);

    cout << ptr4.use_count() << endl;   //1
    cout << ptr5.use_count() << endl;   //1
    ptr4->slots_function();     //有输出
    ptr5->signals();            //无输出,原因是还没有引用A类对象
    cout << "--------------1" << endl;

    //交叉引用
    ptr4->ptr_b = ptr5;
    ptr5->ptr_a = ptr4;
    cout << ptr4.use_count() << endl;   //1,因为类里交叉引用用的wek_ptr
    cout << ptr5.use_count() << endl;   //1,所以,并未让计数器增加
    cout << "---------------2" << endl;

    //调用自身方法可以
    ptr4->slots_function();
    ptr5->signals();
    cout << "--------------3" << endl;

//    ptr5->slots_function(); //错误,交叉引用后也不能直接调别人的方法,需加lock
    ptr5->lock()->slots_function();
    cout << ptr5.use_count() << endl;   //1

    return 0;

        运行结果:

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值