智能指針 unique_ptr shared_ptr weak_ptr
在C98中伤极,智能指針通過一個模板類型"auto_ptr"來實(shí)現(xiàn)。auto_ptr以對象的方式管理分配的內(nèi)存姨伤,并在適當(dāng)?shù)氖录?比如析構(gòu))哨坪,放釋所獲得的堆內(nèi)存。這種對內(nèi)存管理的方式只需要程序員將new操作返回的指針作為auto_ptr的初始值即可乍楚,程序員不用再顯示地調(diào)用delete当编,比如:
auto_ptr(new int);
不過auto_ptr也有一些缺點(diǎn)(拷貝時返回一個左值,不能調(diào)用delete[]等)徒溪;
- shared_ptr
shared_ptr允許多個該智能指針共享的"擁有"同一堆分配對象的內(nèi)存忿偷,與unipue_ptr不同的是,由于在實(shí)現(xiàn)上采用了引用技術(shù)臊泌,所以一旦一個shared_ptr指針放棄了"所有權(quán)"鲤桥,其他的shared_ptr對對象內(nèi)存的引用并不會收到影響。只有在引用技術(shù)歸零的時候渠概,shared_ptr才會真正釋放所占有的堆內(nèi)存空間茶凳。
#include<iostream>
#include<memory>
using namespace std;
int main()
{
shared_ptr<int> sp1(new int(22));
shared_ptr<int> sp2 = sp1;
cout << *sp1 << endl; //22
cout << *sp2 << endl; //22
sp1.reset();
cout << *sp2 << endl; //22
return 0;
}
- unique_ptr
unique_ptr與所指對象的內(nèi)存綁定緊密,不能與其他unique_ptr類型的指針共享所指對象的內(nèi)存高氮,因?yàn)槊總€unique_ptr都是唯一的"擁有"所指向的對象內(nèi)存慧妄。這種"所有權(quán)"僅能通過標(biāo)準(zhǔn)庫的move函數(shù)來轉(zhuǎn)移,一旦"所有權(quán)"轉(zhuǎn)移成功了剪芍,原來的unique_ptr指針就失去了對象內(nèi)存的所有權(quán)塞淹,此時在使用已經(jīng)沒有內(nèi)存所有權(quán)的指針就會導(dǎo)致運(yùn)行時錯誤!W锕饱普!
#include<iostream>
#include<memory>
using namespace std;
int main()
{
unique_ptr<int> up1(new int(11)); //無法復(fù)制的unique_ptr
//unique_ptr<int> up2 = up1; //不能通過編譯
cout << *up1 << endl; //11
unique_ptr<int> up3 = move(up1); //轉(zhuǎn)移up1的內(nèi)存所有權(quán)到up3
cout << *up3 << endl;
//cout << *up1 << endl; //運(yùn)行出錯
up3.reset(); //顯示釋放內(nèi)存
up1.reset(); //不會導(dǎo)致運(yùn)行時錯誤
cout << *up3 << endl; //運(yùn)行錯誤
return 0;
}
- weak_ptr
weak_ptr可以指向shared_ptr指針指向的對象內(nèi)存,但卻不擁有該內(nèi)存状共,而使用weak_ptr成員lock套耕,則可以返回其指向內(nèi)存的一個shared_ptr對象,且在所指對象內(nèi)存已經(jīng)無效時峡继,返回空指針冯袍,這在驗(yàn)證shared_ptr指針的有效性上會很有用。
#include<iostream>
#include<memory>
using namespace std;
void Check(weak_ptr<int> &wp)
{
shared_ptr<int> sp = wp.lock(); //轉(zhuǎn)換為shared_ptr<int>
if (sp != nullptr)
cout << "still" << *sp << endl;
else
cout << "pointer is invalid" << endl;
}
int main()
{
shared_ptr<int> sp1(new int(22));
shared_ptr<int> sp2 = sp1;
weak_ptr<int> wp = sp1; //指向shared_ptr所指對象
cout << *sp1 << endl; //22
cout << *sp2 << endl; //22
Check(wp); //still 22
sp1.reset();
cout << *sp2 << endl; //22
Check(wp); //still 22
sp2.reset();
Check(wp); //pointer is invalid
return 0;
}