weak_ptr需要配合shared_ptr使用,不能直接访问对象,必须调用lock返回非空才能使用。
- 多线程访问,一个线程使用shared_ptr负责内存管理,其它线程只用weak_ptr使用内存。
- 解决shared_ptr循环引用问题。
- 循环引用问题
执行以下程序可以知道,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;
}
- 循环引用问题解决
将其中的一个成员修改为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;
}