C++11智能指針unique_ptr用法使用場(chǎng)景分析
一、概述
C++ 標(biāo)準(zhǔn)模板庫(kù) STL(Standard Template Library) 一共給我們提供了四種智能指針:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已將其摒棄,并提出了 unique_ptr 替代 auto_ptr。雖然 auto_ptr 已被摒棄,但在實(shí)際項(xiàng)目中仍可使用,但建議使用更加安全的 unique_ptr,后文會(huì)詳細(xì)敘述。shared_ptr 和 weak_ptr 則是 C+11 從準(zhǔn)標(biāo)準(zhǔn)庫(kù) Boost 中引入的兩種智能指針。此外,Boost 庫(kù)還提出了 boost::scoped_ptr、boost::scoped_array、boost::intrusive_ptr 等智能指針,雖然尚未得到 C++ 標(biāo)準(zhǔn)采納,但是在開(kāi)發(fā)實(shí)踐中可以使用。
二、實(shí)現(xiàn)原理
- unique_ptr 是 C++ 11 提供的用于防止內(nèi)存泄漏的智能指針中的一種實(shí)現(xiàn),即使在異常發(fā)生時(shí)也可幫助避免資源泄露。
- unique_ptr實(shí)現(xiàn)了獨(dú)享被管理對(duì)象指針的概念,這意味這它可確保一個(gè)對(duì)象和其對(duì)應(yīng)的資源同一時(shí)間只被一個(gè)pointer擁有。一旦擁有者被銷毀或者變成empty或者開(kāi)始擁有另一個(gè)對(duì)象,先前擁有的那個(gè)對(duì)象就會(huì)被銷毀,其任何相應(yīng)資源亦會(huì)被釋放。
- unique_ptr具有->和*運(yùn)算符重載符,因此它可以像普通指針一樣使用。
三、使用場(chǎng)景
先看不使用智能指針,寫(xiě)代碼時(shí)的痛點(diǎn),有可能忘記delete對(duì)象,在某處return的時(shí)候,或者在某處拋出異常,導(dǎo)致末尾的delete語(yǔ)句就沒(méi)機(jī)會(huì)被調(diào)用,導(dǎo)致內(nèi)存泄漏。在還是只new一個(gè)對(duì)象,如果new2,3甚至更多對(duì)象,那管理起來(lái),代碼變的比較復(fù)雜,而且累贅。
這是一種不好的編程風(fēng)格,應(yīng)該避免,因?yàn)樗鼜?fù)雜而又容易出錯(cuò)。
#include <memory>
#include<iostream>
using namespace std;
class A {};
int main()
{
A* ptrA = new A;
try
{
//...
//...
//...
//...
//...
}
catch (...)
{
delete ptrA; //1
throw;
}
delete ptrA; //2
return 0;
}
了解了這個(gè)痛點(diǎn),那么本篇的主角unique_ptr就該閃亮登場(chǎng)了。
unique_ptr對(duì)象可以在自身被銷毀時(shí)釋放其所指向的數(shù)據(jù)。并且unique_ptr它所指向的對(duì)象只有一個(gè)擁有者。
上面糟心的代碼就可以用unique_ptr來(lái)優(yōu)化,在也不需要delete和catch子句。
#include <memory>
#include<iostream>
using namespace std;
class A {};
int main()
{
unique_ptr<A> upA(new A);
//...
//...
return 0;
}
四、unique_ptr的目的
- 獲取某些資源
- 執(zhí)行某些操作
- 將取得的資源釋放掉
五、常用操作
unique_ptr<int> up1(new int(1));//ok unique_ptr<int> up2 = new int(1);//error
構(gòu)造函數(shù)1:可以用原始指針當(dāng)實(shí)參傳給構(gòu)造函數(shù)。
但不能使用=賦值符,那樣的話會(huì)報(bào)錯(cuò),“無(wú)法從“int *”轉(zhuǎn)換為“std::shared_ptr”,是不是很熟悉。
這點(diǎn)和share_ptr一致
構(gòu)造函數(shù)2:make_unique函數(shù)
unique_ptr<string> up4 = make_unique<string>("hello");//ok
構(gòu)造函數(shù)3
int* p = new int; unique_ptr<int> up5(p);//ok unique_ptr<int> up6(p);//logic error,這個(gè)是運(yùn)行期錯(cuò)誤,程序員必須避免這樣的失誤
這樣的問(wèn)題在于sp1,sp2,在丟失p的擁有權(quán)時(shí)釋放相應(yīng)資源,即會(huì)執(zhí)行兩次delete p操作。
不可以對(duì)unique_ptr執(zhí)行copy或者assign操作,只能move,將擁有權(quán)移交給另一個(gè)unique_ptr
int* p = new int; unique_ptr<int> up5(p);//ok unique_ptr<int> up6(up5);//error unique_ptr<int> up7(move(up5));//ok
| 操作 | 效果 |
|---|---|
| unique_ptr up | Default構(gòu)造函數(shù),建立一個(gè)empty unique pointer |
| unique_ptr up(ptr) | 建立unique pointer令其擁有*ptr |
| unique_ptr up(nullptr) | 建立一個(gè)empty unique pointer |
| unique_ptr up(move(up2)) | 建立一個(gè)unique pointer,擁有up2之前擁有的pointer(up2將為empty) |
| up.~unique_ptr() | 析構(gòu)函數(shù),調(diào)用deleter |
| up=up2 | 賦值(sp將共享sp2的擁有權(quán),放棄其先前索擁有對(duì)象的所有權(quán)) |
| up=move(up2) | move assignment(sp2將擁有權(quán)移交給up) |
| up=nullptr | 對(duì)一個(gè)被擁有物調(diào)用delete,i并令為空(等價(jià)up.reset()) |
| up1.swap(up2)==swap(up1,up2) | 交換up1,up2的pointer |
| up.reset() | 放棄擁有權(quán),并重新初始化,使它=empty |
| up.reset(ptr) | 放棄擁有權(quán),重新初始化(擁有*ptr) |
| make_unique(…) | 為一個(gè)新對(duì)象(以傳入的實(shí)參為初值)建立一個(gè)unique pointer |
| up.get() | 返回存儲(chǔ)的pointer,就是返回原始指針,對(duì)該原始指針如果執(zhí)行delete,會(huì)異常。 |
| *up | 同上 |
| up-> | 為擁有物提供成員訪問(wèn) |
| if(up) | 判斷sp是否empty |
| get_deleter(up) | 返回deleter的地址(如果有的話),沒(méi)有返回nullptr |
到此這篇關(guān)于C++11智能指針unique_ptr用法介紹的文章就介紹到這了,更多相關(guān)C++11 unique_ptr智能指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言 map函數(shù)的基礎(chǔ)用法詳解
這篇文章主要為大家介紹了C語(yǔ)言 map函數(shù)的基礎(chǔ)用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-01-01
基于OpenCV和C++ 實(shí)現(xiàn)圖片旋轉(zhuǎn)
這篇文章主要介紹了基于OpenCV和C++ 實(shí)現(xiàn)圖片旋轉(zhuǎn),幫助大家更好的利用c++處理圖片,感興趣的朋友可以了解下2020-12-12
C++11中bind綁定器和function函數(shù)對(duì)象介紹
這篇文章主要介紹了C++11中bind綁定器和function函數(shù)對(duì)象介紹,綁定器,函數(shù)對(duì)象和lambda表達(dá)式只能使用在一條語(yǔ)句中,更多相關(guān)內(nèi)容需要的小伙伴可以參考一下2022-07-07
VC++實(shí)現(xiàn)View內(nèi)容保存為圖片的方法
這篇文章主要介紹了VC++實(shí)現(xiàn)View內(nèi)容保存為圖片的方法,涉及VC++中Bitmap類的save方法相關(guān)使用技巧,需要的朋友可以參考下2016-08-08
C++中成員函數(shù)和友元函數(shù)的使用及區(qū)別詳解
大家好,本篇文章主要講的是C++中成員函數(shù)和友元函數(shù)的使用及區(qū)別詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01
C語(yǔ)言使用回溯法解旅行售貨員問(wèn)題與圖的m著色問(wèn)題
回溯法即是在按條件搜索走不通的情況下退回再選擇其他路線的方法,這里我們來(lái)看C語(yǔ)言使用回溯法解旅行售貨員問(wèn)題與圖的m著色問(wèn)題的方法示例:2016-07-07

