美文网首页
c++ 智能指针(weak_ptr)

c++ 智能指针(weak_ptr)

作者: arkliu | 来源:发表于2022-11-18 09:02 被阅读0次

shared_ptr存在的问题

shared_ptr 内部维护了一个共享的引用计数器,多个shared_ptr可以指向同一个资源,如果出现循环引用的情况,引用计数将永远无法归0, 资源不会被释放。

#include <iostream>
#include <memory>
#include<string>
using namespace std;

class BB;

class AA {
    public:
        string m_name;
        shared_ptr<BB> m_p;
    AA() {
        cout << m_name << "调用了AA的构造函数"<< endl;
    }

    AA(const string &name):m_name(name) {
        cout << "调用了AA的构造函数("<<m_name<<")"<< endl;
    }

    ~AA() {
        cout << "调用了AA的析构函数("<<m_name<<")"<< endl;
    }
};

class BB {
    public:
        string m_name;
        shared_ptr<AA> m_p;
    BB() {
        cout << m_name << "调用了BB的构造函数"<< endl;
    }

    BB(const string &name):m_name(name) {
        cout << "调用了BB的构造函数("<<m_name<<")"<< endl;
    }

    ~BB() {
        cout << "调用了BB的析构函数("<<m_name<<")"<< endl;
    }
};

 
int main() {
    shared_ptr<AA>pa = make_shared<AA>("测试AA");
    shared_ptr<BB>pb = make_shared<BB>("测试BB");

    pa->m_p = pb;
    pb->m_p = pa;
    return 0;
}

上述代码,AA的成员引用BB的对象指针,BB的成员引用AA的对象指针,造成循环引用,此时单纯使用make_shared,就只会执行构造函数,而不会释放资源,执行析构函数。


image.png

引入weak_ptr

weak_ptr是为了配合shared_ptr而引入的,它指向一个由shared_ptr管理的资源,但不影响资源的生命周期,也就是说,将一个weak_ptr绑定到一个shared_ptr,不会改变shared_ptr的引用计数

将上述AA和BB中的引用,分别使用weak_ptr

#include <iostream>
#include <memory>
#include<string>
using namespace std;

class BB;

class AA {
    public:
        string m_name;
        weak_ptr<BB> m_p;
    AA() {
        cout << m_name << "调用了AA的构造函数"<< endl;
    }

    AA(const string &name):m_name(name) {
        cout << "调用了AA的构造函数("<<m_name<<")"<< endl;
    }

    ~AA() {
        cout << "调用了AA的析构函数("<<m_name<<")"<< endl;
    }
};

class BB {
    public:
        string m_name;
        weak_ptr<AA> m_p;
    BB() {
        cout << m_name << "调用了BB的构造函数"<< endl;
    }

    BB(const string &name):m_name(name) {
        cout << "调用了BB的构造函数("<<m_name<<")"<< endl;
    }

    ~BB() {
        cout << "调用了BB的析构函数("<<m_name<<")"<< endl;
    }
};

 
int main() {
    shared_ptr<AA>pa = make_shared<AA>("测试AA");
    shared_ptr<BB>pb = make_shared<BB>("测试BB");

    pa->m_p = pb;
    pb->m_p = pa;
    return 0;
}
image.png

weak_ptr不会影响到shared_ptr的引用计数

int main() {
    shared_ptr<AA>pa = make_shared<AA>("测试AA");
    shared_ptr<BB>pb = make_shared<BB>("测试BB");

    cout << "pa.usecount() = "<<pa.use_count() << endl;
    cout << "pb.usecount() = "<<pa.use_count() << endl;
    
    pa->m_p = pb;
    pb->m_p = pa;

    cout << "pa.usecount() = "<<pa.use_count() << endl;
    cout << "pb.usecount() = "<<pa.use_count() << endl;
    return 0;
}
image.png

weak_ptr使用

  • weak_ptr没有重载-> 和 *操作符,不能直接访问资源
  • 成员函数:
    operator=() 把 shared_ptr或者weak_ptr赋值给weak_ptr
    expired() 判断它指的资源是否过期
    lock() 返回shared_ptr,如果资源已经过期,返回空的shared_ptr
    reset() 将当前weak_ptr指针置为空
    swap() 交换
int main() {
    shared_ptr<AA>pa = make_shared<AA>("测试AA");
    {
        shared_ptr<BB>pb = make_shared<BB>("测试BB");
        pa->m_p = pb;
        pb->m_p = pa;

        shared_ptr<BB> pp = pa->m_p.lock();
        if (pp == nullptr)
        {
            cout << "语句块内部,pa->m_p已经过期" << endl;
        } else {
            cout << "语句块内部,pa->m_p没有过期  " << pp->m_name << endl;
        }
    }

    shared_ptr<BB> pp = pa->m_p.lock();
    if (pp == nullptr)
    {
        cout << "语句块外部,pa->m_p已经过期" << endl;
    } else {
        cout << "语句块外部,pa->m_p没有过期  " << pp->m_name << endl;
    }
    return 0;
}
image.png

相关文章

网友评论

      本文标题:c++ 智能指针(weak_ptr)

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