我们先来看一段代码:
#include<iostream>
using namespace std;
class B; //声明
class A
{
public:
shared_ptr<B> pb_;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
shared_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
};
void fun()
{
shared_ptr<B> pb(new B());
shared_ptr<A> pa(new A());
cout << pb.use_count() << endl; //1
cout << pa.use_count() << endl; //1
pb->pa_ = pa;
pa->pb_ = pb;
cout << pb.use_count() << endl; //2
cout << pa.use_count() << endl; //2
}
int main()
{
fun();
system("pause");
return 0;
}
输出结果为
1
1
2
2
请按任意键继续. . .
我们可以看到,智能指针share_ptr管理的两个对象并没有被析构,在两个share_ptr对象出现交叉引用时,两个对象的引用计数均为2,而当离开函数fun时,pb,pa对象的引用计数均减1,但二者的引用计数均为减到0,无法触发所管理对象的析构,因此这两个对象的引用计数由于永远无法降为0而永远无法释放,导致内存泄漏。
智能指针weak_ptr可以很好的解决这个问题。
我们可以将两个对象成员中的其中一个智能指针改为weak_ptr就可以了,如,我们把类A里面的shared_ptr pb_,改为weak_ptr pb_
class B; //声明
class A
{
public:
weak_ptr<B> pb_;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
shared_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
};
void fun()
{
shared_ptr<B> pb(new B());
shared_ptr<A> pa(new A());
cout << pb.use_count() << endl; //1
cout << pa.use_count() << endl; //1
pb->pa_ = pa; // pa_是强引用,A对象引用计数加1,为2
pa->pb_ = pb; // pb_是弱引用,B对象引用计数不变,为1
cout << pb.use_count() << endl; //1 B对象的引用计数
cout << pa.use_count() << endl; //2 A对象的引用计数
}
运行结果
1
1
1
2
B delete
A delete
请按任意键继续. . .
在退出fun函数时,pa, pb对象析构,pa,pb的引用计数均减1,pb管理对象的引用计数为0,pa管理对象的引用计数为1,B对象析构,析构时包含的pa_对象被析构,引用计数减1,此时pa_管理对象引用计数为0,A对象析构。