★14.关于std--shared_ptr

2017-06-30  本文已影响0人  iDragonfly

注意事项

循环引用

循环引用问题

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");
}

解决方案

删除器

绑定删除器

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

改变删除器

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;
});
上一篇下一篇

猜你喜欢

热点阅读