• 智能指针weak_ptr记录


    智能指针weak_ptr为弱共享指针,实际上是share_ptr的辅助指针,不具备指针的功能。主要是为了协助 shared_ptr 工作,可用来观测资源的使用情况。weak_ptr 只对 shared_ptr 进行引用,而不改变其引用计数,当被观察的 shared_ptr 失效后,相应的 weak_ptr 也相应失效。use_count() 可以观测资源的引用计数,lock()返回一个对象的可用的share_ptr,若weak_ptr.expired()为true过期,则返回一个空的share_ptr。

    构造:

    std::shared_ptr<int> sp(new int);
    std::weak_ptr<int> wp1;
    std::weak_ptr<int> wp2(wp1);
    std::weak_ptr<int> wp3(sp);
    std::cout << "use_count:
    ";
    std::cout << "wp1: " << wp1.use_count() << '
    ';
    std::cout << "wp2: " << wp2.use_count() << '
    ';
    std::cout << "wp3: " << wp3.use_count() << '
    ';

    输出引用计数:

    过期判断:

    std::shared_ptr<int> shared(new int(10));
    std::weak_ptr<int> weak(shared);
    std::cout << "1. weak " << (weak.expired() ? "is" : "is not") << " expired
    ";
    shared.reset();
    std::cout << "2. weak " << (weak.expired() ? "is" : "is not") << " expired
    ";

    输出:

    lock()返回可用的share_ptr或空share_ptr

    std::shared_ptr<int> sp1, sp2;
    std::weak_ptr<int> wp;
    sp1 = std::make_shared<int>(20); // sp1
    wp = sp1;                        // sp1, wp
    sp2 = wp.lock();                 // sp1, wp, sp2
    sp1.reset();                     //      wp, sp2
    sp1 = wp.lock();                 // sp1, wp, sp2
    std::cout << "*sp1: " << *sp1 << '
    ';
    std::cout << "*sp2: " << *sp2 << '
    ';

    输出:

    #########################################################################################################

    一个问题:shared_ptr是采用引用计数的智能指针,多个shared_ptr可以指向同一个动态对象,并共用了一个引用计数器。因此会出现循环引用的问题,导致计数器无法减一,因而内容在该销毁的地方没有释放。

    eg:

    class Brother;
    class Sister
    {
    public:
        Sister() { cout << "Sister Constructor..." << endl; }
        ~Sister() { cout << "Sister Destructor..." << endl; }
        shared_ptr<Brother> _bro;
    };
    class Brother
    {
    public:
        Brother() { cout << "Brother Constructor..." << endl; }
        ~Brother() { cout << "Brother Destructor..." << endl; }
        shared_ptr<Sister> _sis;
    };
    
    
    shared_ptr<Sister> sps = make_shared<Sister>();
    shared_ptr<Brother> spb = make_shared<Brother>();
    sps->_bro = spb;
    spb->_sis = sps;
    std::cout << "sps use_cout:" << sps.use_count() << std::endl;
    std::cout << "spb use_cout:" << spb.use_count() << std::endl;

    输出:

    引用计数器为2,析构函数没有调用,出现程序执行完内容没有释放。

    使用weak_ptr来处理这一问题,只需要将相互引用使用weak_ptr来替换share_ptr的引用即可

    class Sister
    {
    public:
        Sister() { cout << "Sister Constructor..." << endl; }
        ~Sister() { cout << "Sister Destructor..." << endl; }
        weak_ptr<Brother> _bro;
    };
    class Brother
    {
    public:
        Brother() { cout << "Brother Constructor..." << endl; }
        ~Brother() { cout << "Brother Destructor..." << endl; }
        weak_ptr<Sister> _sis;
    };

    同样的输出代码:

    正常析构,程序执行完释放内容。

  • 相关阅读:
    Div在BOdy中居中
    c_lc_填充每个节点的下一个右侧节点指针 I~II(递归)
    c_pat_哈密顿回路 & 最大点集 & 是否是旅行商路径 & 欧拉路径 & 最深的根(邻接矩阵存图)
    c_lc_二叉搜索树的最近公共祖先 & 二叉树的最近公共祖先(利用性质 | 从p,q开始存储每个结点的父亲)
    c_pat_树题大杂烩(利用性质)
    现在的我,理解了这种「激情」
    b_pat_排成最小的数字 & 月饼(字符串拼接比较a+b<b+a)
    c_lc_二叉搜索树中的众数(中序遍历+延迟更新前驱结点)
    b_pat_分享 & 链表排序 & 链表去重(链表模拟)
    b_pat_弹出序列(栈模拟)
  • 原文地址:https://www.cnblogs.com/tyche116/p/12082946.html
Copyright © 2020-2023  润新知