美文网首页
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