- 強智能指針:資源每被強智能指針引用一次,引用計數+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都是線程安全的智能智能指針;
- 定義的地方或者生成資源的地方一定的是強智能指針,引用資源的地方一定使用弱智能指針。