weak_ptr需要配合shared_ptr使用,不能直接访问对象,必须调用lock返回非空才能使用。

  1. 多线程访问,一个线程使用shared_ptr负责内存管理,其它线程只用weak_ptr使用内存。
  2. 解决shared_ptr循环引用问题。
  • 循环引用问题 alt 执行以下程序可以知道,main函数退出前pA与pB引用计数均为2,那退出时引用计数就会变为1,所以不会执行析构函数,发现内存泄露。
clas***;
class A
{
public:
    shared_ptr<B> p;
    ~A()
    {
        cout << "~A" << endl;
    }
};

clas***
{
public:
    shared_ptr<A> p;
    ~B()
    {
        cout << "~B" << endl;
    }
};

int main()
{ 
    shared_ptr<A> pA(new A);
    shared_ptr<B> pB(new B);

    pA->p = pB;
    pB->p = pA;
    cout << pA.use_count() << endl;
    cout << pB.use_count() << endl;
    
    return 0;
}

  • 循环引用问题解决 alt 将其中的一个成员修改为weak_ptr引用即可。
    执行以下程序可知,main函数退出前pA与pB引用计数分别为1和2,原因很简单,B对象对A对象的引用采用weak_ptr不会增加pA的引用计数。这样函数在退出时,由于pA引用计数为1,A对象可以正确析构。A析构后,pB引用计数减1变成1,所以B对象也能正确析构。程序结果也是如此,先析构A,再析构B(与“一般先构造的对象后析构”不同)
clas***;
class A
{
public:
    shared_ptr<B> p;
    ~A**()**
    {
        cout << "~A" << endl;
    }
};

clas***
{
public:
    weak_ptr<A> p;
    ~B()
    {
        cout << "~B" << endl;
    }
};

int main()
{ 
    shared_ptr<A> pA(new A);
    shared_ptr<B> pB(new B);

    pA->p = pB;
    pB->p = pA;
    cout << pA.use_count() << endl;
    cout << pB.use_count() << endl;
    
    return 0;
}