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

目录

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;

        运行结果:

        

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是C++中三种智能指针的实现原理和区别。 首先,我们需要明确一下什么是智能指针智能指针是一种C++中的类,它的行为类似于指针,但是它具有一些额外的功能,比如自动内存管理。智能指针能够自动释放所管理的对象,从而避免内存泄漏和野指针的问题。 下面我们分别介绍shared_ptr、unique_ptrweak_ptr三种智能指针的实现原理和区别。 ## shared_ptr shared_ptr是一种引用计数智能指针,它的实现原理是通过使用引用计数来跟踪有多少个shared_ptr对象指向同一个对象。每当一个新的shared_ptr对象指向该对象时,引用计数就会增加1,当一个shared_ptr对象被销毁时,引用计数就会减少1。当引用计数变为0时,就表示没有任何shared_ptr对象指向该对象,此时该对象将被自动销毁。 shared_ptr的优点是可以共享资源,缺点是有可能出现循环引用的问题,导致内存泄漏。为了避免这个问题,C++11中引入了weak_ptr。 ## unique_ptr unique_ptr是一种独占式智能指针,它的实现原理是通过禁止拷贝和赋值来保证同一时间只有一个unique_ptr对象指向一个对象。当一个unique_ptr对象被销毁时,它所管理的对象也将会被销毁。为了更好地支持移动语义,C++11中引入了move语义,使得unique_ptr对象可以被移动而不是被复制。 unique_ptr的优点是可移植性好,可以避免循环引用的问题,缺点是不能共享资源。 ## weak_ptr weak_ptr是一种弱引用智能指针,它的实现原理是与shared_ptr配合使用。weak_ptr不会增加引用计数,它只是提供了对所指向对象的一个非拥有性的访问。当所指向的对象被销毁后,weak_ptr将自动失效。 weak_ptr的优点是可以避免循环引用的问题,缺点是不能访问所指向对象的成员变量和成员函数。如果需要访问所指向对象的成员变量和成员函数,需要将weak_ptr转换为shared_ptr。 下面是一个示例代码,展示了shared_ptr、unique_ptrweak_ptr的使用方式: ```c++ #include <iostream> #include <memory> class A { public: A() { std::cout << "A()" << std::endl; } ~A() { std::cout << "~A()" << std::endl; } void foo() { std::cout << "foo()" << std::endl; } }; int main() { // shared_ptr std::shared_ptr<A> p1(new A()); std::shared_ptr<A> p2(p1); std::cout << "p1.use_count() = " << p1.use_count() << std::endl; std::cout << "p2.use_count() = " << p2.use_count() << std::endl; // unique_ptr std::unique_ptr<A> p3(new A()); // std::unique_ptr<A> p4(p3); // error: copy constructor is deleted std::unique_ptr<A> p5(std::move(p3)); if (p3 == nullptr) { std::cout << "p3 is nullptr" << std::endl; } // weak_ptr std::shared_ptr<A> p6(new A()); std::weak_ptr<A> p7(p6); std::cout << "p7.use_count() = " << p7.use_count() << std::endl; if (auto p8 = p7.lock()) { p8->foo(); } else { std::cout << "p7 is expired" << std::endl; } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值