美文网首页
★14.关于std--shared_ptr

★14.关于std--shared_ptr

作者: iDragonfly | 来源:发表于2017-06-30 22:18 被阅读0次

    注意事项

    • 永远只用make_shared<T>make_unique<T>的方式初始化和构造,因为效率高。
    • 类型转换请使用:static_pointer_cast<T>dynamic_pointer_cast<T>

    循环引用

    循环引用问题

    class B;         // 前向声明
    
    class A {
    public:
        // 正确,不会增减引用计数,不造成智能指针循环引用,但是weak_ptr没有->和*,需要使用时必须先调用其lock函数返回一个shared_ptr然后才能用
        // std::weak_ptr<B> m_b;
    
        // 错误,会造成智能指针循环引用
        std::shared_ptr<B> m_b;
    };
    
    class B {
    public:
        std::shared_ptr<A> m_a;
    };
    
    
    int main() {
        int n = 999999;
        while (n--) {
            std::shared_ptr<A> a = std::make_shared<A>();   // new出来的A的引用计数此时为1
            std::shared_ptr<B> b = std::make_shared<B>();   // new出来的B的引用计数此时为1
            a->m_b = b;  // B的引用计数增加为2
            b->m_a = a;  // A的引用计数增加为2
        }
        // b先出作用域,B的引用计数减少为1,不为0, 所以堆里的B空间没有被释放,且B持有的A也没有机会析构,A的引用计数也完全没减少
        // a后出作用域,同理A的引用计数减少为1,不为0,所以堆里的A的空间也没有被释放
        return system("pause");
    }
    

    解决方案

    • 建模时明确所有权关系,所有者应该使用std::shared_ptr指向被持有者。若被持有者想要引用所有者则必须要使用std::weak_ptr指向所有者。

    删除器

    绑定删除器

    // shared_ptr可以绑定删除器
    std::shared_ptr<int> p(new int, [](int * t) { delete t; });
    

    改变删除器

    • shared_ptr可以在运行时改变删除器,unique_ptr不可以。
    std::shared_ptr<int> p(new int, [](int * t) { delete t; });
    p.reset(new int, [](int * t) {
        std::cout << "shared_ptr可以在运行时改变删除器" << std::endl;
        delete t;
    });
    

    相关文章

      网友评论

          本文标题:★14.关于std--shared_ptr

          本文链接:https://www.haomeiwen.com/subject/weoicxtx.html