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)采納,但是在開發(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或者開始擁有另一個(gè)對(duì)象,先前擁有的那個(gè)對(duì)象就會(huì)被銷毀,其任何相應(yīng)資源亦會(huì)被釋放。
- unique_ptr具有->和*運(yùn)算符重載符,因此它可以像普通指針一樣使用。
三、使用場(chǎng)景
先看不使用智能指針,寫代碼時(shí)的痛點(diǎn),有可能忘記delete對(duì)象,在某處return的時(shí)候,或者在某處拋出異常,導(dǎo)致末尾的delete語(yǔ)句就沒機(jī)會(huì)被調(diào)用,導(dǎo)致內(nèi)存泄漏。在還是只new一個(gè)對(duì)象,如果new2,3甚至更多對(duì)象,那管理起來,代碼變的比較復(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來優(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ò),“無法從“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ò)誤,程序員必須避免這樣的失誤
這樣的問題在于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-> | 為擁有物提供成員訪問 |
| if(up) | 判斷sp是否empty |
| get_deleter(up) | 返回deleter的地址(如果有的話),沒有返回nullptr |
到此這篇關(guān)于C++11智能指針unique_ptr用法介紹的文章就介紹到這了,更多相關(guān)C++11 unique_ptr智能指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中遞歸的實(shí)際應(yīng)用與經(jīng)典問題
函數(shù)以及函數(shù)的遞歸調(diào)用是學(xué)習(xí)C語(yǔ)言必須要掌握的內(nèi)容,且遞歸作為經(jīng)典的算法思想被廣泛應(yīng)用于程序設(shè)計(jì)中,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中遞歸的實(shí)際應(yīng)用與經(jīng)典問題的相關(guān)資料,需要的朋友可以參考下2021-09-09
C/C++中關(guān)于字符串的常見函數(shù)操作大全
這篇文章主要介紹了C/C++中關(guān)于字符串的常見函數(shù)操作,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
C/C++ 原生API實(shí)現(xiàn)線程池的方法
線程池,簡(jiǎn)單來說就是有一堆已經(jīng)創(chuàng)建好的線程,接下來通過本文給大家介紹C/C++ 原生API實(shí)現(xiàn)線程池的方法,感興趣的朋友跟隨小編一起看看吧2021-11-11
C語(yǔ)言對(duì)磁盤文件進(jìn)行快速排序簡(jiǎn)單實(shí)例
這篇文章主要介紹了C語(yǔ)言對(duì)磁盤文件進(jìn)行快速排序簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-06-06
C語(yǔ)言實(shí)現(xiàn)變色進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)一個(gè)變色的進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
C++實(shí)現(xiàn)LeetCode(159.最多有兩個(gè)不同字符的最長(zhǎng)子串)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(159.最多有兩個(gè)不同字符的最長(zhǎng)子串),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

