weak_ptr的使用


前言

weak_ptr并不拥有指针的所有权,因此并不能调用->和解引用。
那为什么要使用weak_ptr呢?
如果A类中有一个需求需要存储其他A类对象的信息,如果使用shared_ptr,那么在销毁时会遇到循环依赖的问题,所以我们这里需要用一个不需要拥有所有权的指针来标记该同类对象,weak_ptr可以通过lock()函数来提升为shared_ptr(类型对象)。


提示:以下是本篇文章正文内容,下面案例可供参考

一、weak_ptr不能解引用

二、weak_ptr的使用

使用weak_ptr并不会使引用计数值+1,lock函数可以使weak_ptr转换为shared_ptr。

#include<iostream>
#include<memory>
#include"cat.h"
using namespace std;


int main(int argc, char *argv[])
{
    std::shared_ptr<Cat> s_p_c1=std::make_shared<Cat>("C1");
    std::weak_ptr w_p_c1(s_p_c1);
    //use_count()
    cout<<"w_p_c1:"<<w_p_c1.use_count()<<endl;
    cout<<"s_p_c1:"<<s_p_c1.use_count()<<endl;
    //w_p_c1->cat_info();
    std::shared_ptr<Cat> s_p_c2=w_p_c1.lock();
    cout<<"w_p_c1:"<<w_p_c1.use_count()<<endl;
    cout<<"s_p_c1:"<<s_p_c1.use_count()<<endl;
    cout<<"s_p_c2:"<<s_p_c2.use_count()<<endl;
    cout<<"----- yz -----"<<endl;
    return 0;
}

运行结果:
在这里插入图片描述

三、用shared_ptr产生环形引用问题

1.在这里需要对cat.h稍微修改一下(main.cpp, cat.h, cat.cpp在unique_ptr的使用一文中有提到)

#ifndef CAT_H
#define CAT_H
#include<string>
#include<iostream>
#include<memory>
class Cat
{
    public:
    Cat(std::string name);
    Cat()=default;
    ~Cat();
    void cat_info() const
    {
        std::cout<<"cat info name:"<<name<<std::endl;
    }
    std::string get_name() const
    {
        return name;
    }
    void set_cat_name(const std::string &name)
    {
        this->name=name;
    }
    void set_friend(std::shared_ptr<Cat> c)
    {
        m_friend=c;//这里改
    }
    private:
    std::string name{"Mimi"};
    std::shared_ptr<Cat> m_friend;//这里改
};
#endif

主函数:

#include<iostream>
#include<memory>
#include"cat.h"
using namespace std;


int main(int argc, char *argv[])
{
    // std::shared_ptr<Cat> s_p_c1=std::make_shared<Cat>("C1");
    std::shared_ptr<Cat> c3=std::make_shared<Cat>("C3");
    std::shared_ptr<Cat> c4=std::make_shared<Cat>("C4");
    c3->set_friend(c4);
    c4->set_friend(c3);
    cout<<"----- yz -----"<<endl;
    return 0;
}

实验结果:
在这里插入图片描述
结论:上面的c3和c4在程序运行结束后并没有被销毁。
下面的实验来验证是环形引用的问题导致对象不能销毁:将12、13行注释:

#include<iostream>
#include<memory>
#include"cat.h"
using namespace std;


int main(int argc, char *argv[])
{
    // std::shared_ptr<Cat> s_p_c1=std::make_shared<Cat>("C1");
    std::shared_ptr<Cat> c3=std::make_shared<Cat>("C3");
    std::shared_ptr<Cat> c4=std::make_shared<Cat>("C4");
    // c3->set_friend(c4);
    // c4->set_friend(c3);
    cout<<"----- yz -----"<<endl;
    return 0;
}

实验结果:
在这里插入图片描述
结论:将那两行注释之后,程序运行结束后,c3和c4销毁,说明是环形引用造成的问题。
2.使用weak_ptr解决环形引用的问题
修改cat.h文件:

#ifndef CAT_H
#define CAT_H
#include<string>
#include<iostream>
#include<memory>
class Cat
{
    public:
    Cat(std::string name);
    Cat()=default;
    ~Cat();
    void cat_info() const
    {
        std::cout<<"cat info name:"<<name<<std::endl;
    }
    std::string get_name() const
    {
        return name;
    }
    void set_cat_name(const std::string &name)
    {
        this->name=name;
    }
    void set_friend(std::shared_ptr<Cat> c)//这里不用改
    {
        m_friend=c;
    }
    private:
    std::string name{"Mimi"};
    std::weak_ptr<Cat> m_friend;//原来是std::shared_ptr<Cat> m_friend;
};
#endif

再次运行:

#include<iostream>
#include<memory>
#include"cat.h"
using namespace std;


int main(int argc, char *argv[])
{
     std::shared_ptr<Cat> c3=std::make_shared<Cat>("C3");
    std::shared_ptr<Cat> c4=std::make_shared<Cat>("C4");
    c3->set_friend(c4);
    c4->set_friend(c3);
    cout<<"----- yz -----"<<endl;
    return 0;
}

实验结果:
在这里插入图片描述
对象能够正常销毁。


总结

weak_ptr能够解决环形引用问题,是shared_ptr的补充。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值