zoukankan      html  css  js  c++  java
  • shared_ptr use_count_和weak_count_作用,循环引用问题

    use_count:对象数据的引用计数,每次引用计数加1,每次释放计数减一,当计数为0时,释放对象空间。

    weak_count:引用计数的计数,即use_count的计数。

        如果对象数据地址多次赋值给shared_ptr<>则use_count++,而weak_count==1;

        如果对象数据地址多次赋值给weak_ptr<>则use_count不变,而weak_count++;

    循环引用问题(从其他大牛那里抄的,例子很有带入感):

    例子1:

    struct Node
    {
        Node(int value)
        :_value(value)
        {
            cout << "Node()" << endl;
        }
        ~Node()
        {
            cout << "~Node()" << endl;
        }
        shared_ptr<Node> _prev;
        shared_ptr<Node> _next;
        int _value;
    };
     
    void Test2()
    {
        shared_ptr<Node> sp1(new Node(1));
        shared_ptr<Node> sp2(new Node(2));
        cout << sp1.use_count() << endl;
        cout << sp2.use_count() << endl;
        sp1->_next = sp2;
        sp2->_prev = sp1;
        cout << sp1.use_count() << endl;
        cout << sp2.use_count() << endl;
    }
     
    int main()
    {
        Test2();
        return 0;
    }

    若本地没有安装boost库,可以用线上c++工具测试(https://c.runoob.com/compile/12)

    运行后发现没有调用析构函数,

    原因:

    由于先构造的后释放,后构造的先释放可知,先释放的是sp2,那么因为它的引用计数为2,减去1之后就成为了1,不能释放空间,因为还有其他的对象在管理这块空间。但是sp2这个变量已经被销毁,因为它是栈上的变量,但是sp2管理的堆上的空间并没有释放。
    接下来释放sp1,同样,先检查引用计数,由于sp1的引用计数也是2,所以减1后成为1,也不会释放sp1管理的动态空间。
     
    通俗点讲:就是sp2要释放,那么必须等p1释放了,而sp1要释放,必须等sp2释放,所以,最终,它们两个都没有释放空间。
     
    解决办法:
    shared_ptr<Node> _prev;
    shared_ptr<Node> _next;
    改成
    weak_ptr<Node> _prev;
    weak_ptr<Node> _next;
     
    例子2:
    typedef boost::shared_ptr parent_ptr;  
    typedef boost::shared_ptr children_ptr;  
      
    class parent  
    {  
    public:  
        ~parent() { std::cout <<"destroying parent
    "; }  
      
    public:  
        children_ptr children;  
    };  
      
    class children  
    {  
    public:  
        ~children() { std::cout <<"destroying children
    "; }  
      
    public:  
        parent_ptr parent;  
    };  
      
    void test()  
    {  
        parent_ptr father(new parent());  
        children_ptr son(new children);  
      
        father->children = son;  
        son->parent = father;  
    }  
      
    void main()  
    {  
        std::cout<<"begin test...
    ";  
        test();  
        std::cout<<"end test.
    ";  
    }  
     
    参考:
  • 相关阅读:
    Mobile Widget——让开发移动应用就像做网页
    Qcon大会上电子工业出版社博文视点提供全程图书支持
    电子工业出版社PPT图书优秀作者上海书城讲座
    2天玩转单反相机引领时尚娱乐新生活
    Android开发之ADB使用
    交大研究生,就一个字牛
    程序员能力矩阵
    主流浏览器内核概览
    网站成功的三十三个法则
    Checkstyle, PMD, Findbugs对比
  • 原文地址:https://www.cnblogs.com/workharder/p/14405778.html
Copyright © 2011-2022 走看看