使用示例方式記錄weak_ptr使用方法

#include <iostream>
#include <memory>

/*
// pa與pb相互引用,導致引用計數不能減爲0,導致內存泄漏
class B;
class A {
public:
    std::shared_ptr<B> m_pb;
    ~A() {
        std::cout << "A deleted" << std::endl;
    }
};

class B {
public:
    std::shared_ptr<A> m_pa;
    ~B() {
        std::cout << "B deleted" << std::endl;
    }
};
*/

// 爲了解決上述問題,將其中一個成員改爲weak_ptr,weak_ptr與shared_ptr的區別就是不計數。
// 資源B的引用開始就只有1,當pb析構時,B的計數變爲0,B得到釋放,B釋放的同時也會使A的計數減1。
// 同時pa析構時使A的計數減1,那麼A的計數爲0,A得到釋放。
class B;
class A {
public:
    std::shared_ptr<B> m_pb;
    ~A() {
        std::cout << "A deleted" << std::endl;
    }
};

class B {
public:
    std::weak_ptr<A> m_pa;
    ~B() {
        std::cout << "B deleted" << std::endl;
    }
};
void func() {
    
    std::shared_ptr<A> pa(new A());
    std::shared_ptr<B> pb(new B());
    
    std::cout << "before reference pa.use_count():" << pa.use_count() << std::endl;
    std::cout << "before reference pb.use_count():" << pb.use_count() << std::endl;
    
    pa->m_pb = pb;
    pb->m_pa = pa;
    // weak_ptr只能使用shared_ptr或者weak_ptr進行初始化
    std::cout << "after reference pa.use_count():" << pa.use_count() << std::endl;
    std::cout << "after reference pb.use_count():" << pb.use_count() << std::endl;

    // 獲取當前資源被多少個指針進行引用
    std::cout << "pb->m_pa.use_count():" << pb->m_pa.use_count() << std::endl;
    
    // weak_ptr管理的資源不能被直接訪問,需要通過lock函數從其中獲取shared_ptr纔可以被訪問。
    std::shared_ptr<A> tempA = pb->m_pa.lock();

    // 使用expired查看當前weak_ptr是否已經不指向任何數據
    std::cout << "pb->m_pa.expired() :" << (pb->m_pa.expired() ? " is " : " is not ") << "expire"<< std::endl;
    pb->m_pa.reset();
    std::cout << "pb->m_pa.expired() :" << (pb->m_pa.expired() ? " is " : " is not ") << "expire" << std::endl;
}

int main() {
    func();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章