- 强智能指针:资源每被强智能指针引用一次,引用计数+1,释放引用计数-1,如shared_ptr;
- 弱智能指针:仅仅起到观察作用,观察对象释放还存在,不改变资源的引用计数,也就是说对象的引用计数是否等于0,如weak_ptr.
强智能指针的使用,带来资源的交叉引用问题:
class B;
class A{
public:
A(){ std::cout<<"A()"<<std::endl; }
~A() { std::cout<<" ~A()"<<std::endl; }
shared_ptr<B> ptrb;
};
class B{
public:
B(){ std::cout<<"B()"<<std::endl; }
~B() { std::cout<<" ~B()"<<std::endl; }
shared_ptr<A> ptra;
};
int main(){
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
std::cout<<pa.use_count()<<std::endl;//打印对象pa的引用计数
std::cout<<pb.use_count()<<std::endl;
pa->ptrb = pb;
pb->ptra = pa;
std::cout<<pa.use_count()<<std::endl;
std::cout<<pb.use_count()<<std::endl;
return 0;
}
解决上述问题,引入弱智能指针:
class B;
class A{
public:
A(){ std::cout<<"A()"<<std::endl; }
~A() { std::cout<<" ~A()"<<std::endl; }
weak_ptr<B> ptrb;
void show(){
std::cout<<"A::show()"<<std::endl;
}
};
class B{
public:
B(){ std::cout<<"B()"<<std::endl; }
~B() { std::cout<<" ~B()"<<std::endl; }
weak_ptr<A> ptra; //资源引用时用弱智能指针,而不是强智能指针
void CallAshow(){
//将ptra提升为强智能指针,调用lock(),否则无法访问A的方法,只能起观察的作用
shared_ptr<A> p = ptra.lock();
if(p != nullptr){
p->show();
}
}
};
int main(){
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa->ptrb = pb;
pb->ptra = pa;
pb->CallAshow();
std::cout<<pa.use_count()<<std::endl;
std::cout<<pb.use_count()<<std::endl;
return 0;
}
执行结果:
A()
B()
A::show()
1
1
~B()
~A()
总结:
- 强智能指针交叉引用会造成资源泄露问题,引入弱智能指针解决;
- 强智能指针引起引用计数+1,弱智能指针不会引起引用计数+1;
- 弱智能智能在有需要的时候可以提升为强智能指针,通过判断返回值是否为nullptr查看是否提升成功;
weak_ptr<A> ptra;
shared_ptr<A> p = ptra.lock();
if(p != nullptr){
//do something
}
- shared_ptr和weak_ptr都是线程安全的智能智能指针;
- 定义的地方或者生成资源的地方一定的是强智能指针,引用资源的地方一定使用弱智能指针。