shared_ptr
shared_ptr是帶引用計數(shù)的指針。只有當(dāng)引用計數(shù)為 0 的時候,才會釋放所指的對象。
shared_ptr 不需要程序員手工調(diào)用 AddRef 和 Release 函數(shù),進一步減小了內(nèi)存出錯的可能性。
int main( )
{
std::shared_ptr<double> p_first(new double); // 引用計數(shù)=1
{
std::shared_ptr<double> p_copy = p_first ; // 引用計數(shù)+1=2
*p_copy = 1.234;
} // 局部變量p_copy釋放,引用計數(shù)-1=1,double對象仍存在
return 0; // p_first釋放,指向double的shared_ptr引用計數(shù)=0,double對象被釋放
}
使用 shared_ptr 要注意的可能會引起循環(huán)引用的代碼結(jié)構(gòu)。比如:有對象 A 和 B,其各有一個指針指向?qū)Ψ健?/p>
class A
{
...
std::shared_ptr<B> pB;
...
};
class B
{
...
std::shared_ptr<A> pA;
...
};
int main () {
std::shared_ptr<A> a(new A());
std::shared_ptr<B> b(new B());
a->b = b;
b->a = a;
return 0;
}
在程序運行結(jié)束時,A,B的對象都不能夠被正確釋放,因為:
如果釋放A,但B內(nèi)部仍存有指向A的一個引用計數(shù);
如果釋放B,但A內(nèi)部仍存有指向B的一個引用計數(shù)。
weak_ptr
類似線程安全方面的死鎖問題,為了解決循環(huán)引用問題,可以使用 weak_ptr。
weak_ptr并不擁有它所指向的對象,因此不影響該對象的銷毀與否。
對上例做如下調(diào)整后,解決對象不能正常銷毀的問題。
class A
{
...
std::weak_ptr<B> pB;
...
};
class B
{
...
std::weak_ptr<A> pA;
...
};
int main () {
std::shared_ptr<A> a(new A());
std::shared_ptr<B> b(new B());
a->b = b;
b->a = a;
return 0;
}
weak_ptr的特點:
- weak_ptr指向的是一個被shared_ptr所指向的對象。
- weak_ptr可以用來決定該對象是否已被銷毀。
- weak_ptr不能被直接解引用;
想要訪問其內(nèi)部所保存的指針,必須通過shared_ptr,有兩種方法:
第一,以weak_ptr為參數(shù),構(gòu)造一個shared_ptr.
shared_ptr<B> pB(a->b);
pB->foo();
第二,通過weak_ptr的lock()成員函數(shù),返回一個shared_ptr
shared_ptr<B> pB = a->b.lock();
pB->foo();