C++11智能指針unique_ptr用法使用場景分析
一、概述
C++ 標準模板庫 STL(Standard Template Library) 一共給我們提供了四種智能指針:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已將其摒棄,并提出了 unique_ptr 替代 auto_ptr。雖然 auto_ptr 已被摒棄,但在實際項目中仍可使用,但建議使用更加安全的 unique_ptr,后文會詳細敘述。shared_ptr 和 weak_ptr 則是 C+11 從準標準庫 Boost 中引入的兩種智能指針。此外,Boost 庫還提出了 boost::scoped_ptr、boost::scoped_array、boost::intrusive_ptr 等智能指針,雖然尚未得到 C++ 標準采納,但是在開發(fā)實踐中可以使用。
二、實現(xiàn)原理
- unique_ptr 是 C++ 11 提供的用于防止內存泄漏的智能指針中的一種實現(xiàn),即使在異常發(fā)生時也可幫助避免資源泄露。
- unique_ptr實現(xiàn)了獨享被管理對象指針的概念,這意味這它可確保一個對象和其對應的資源同一時間只被一個pointer擁有。一旦擁有者被銷毀或者變成empty或者開始擁有另一個對象,先前擁有的那個對象就會被銷毀,其任何相應資源亦會被釋放。
- unique_ptr具有->和*運算符重載符,因此它可以像普通指針一樣使用。
三、使用場景
先看不使用智能指針,寫代碼時的痛點,有可能忘記delete對象,在某處return的時候,或者在某處拋出異常,導致末尾的delete語句就沒機會被調用,導致內存泄漏。在還是只new一個對象,如果new2,3甚至更多對象,那管理起來,代碼變的比較復雜,而且累贅。
這是一種不好的編程風格,應該避免,因為它復雜而又容易出錯。
#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; }
了解了這個痛點,那么本篇的主角unique_ptr就該閃亮登場了。
unique_ptr對象可以在自身被銷毀時釋放其所指向的數(shù)據(jù)。并且unique_ptr它所指向的對象只有一個擁有者。
上面糟心的代碼就可以用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
構造函數(shù)1:可以用原始指針當實參傳給構造函數(shù)。
但不能使用=賦值符,那樣的話會報錯,“無法從“int *”轉換為“std::shared_ptr”,是不是很熟悉。
這點和share_ptr一致
構造函數(shù)2:make_unique函數(shù)
unique_ptr<string> up4 = make_unique<string>("hello");//ok
構造函數(shù)3
int* p = new int; unique_ptr<int> up5(p);//ok unique_ptr<int> up6(p);//logic error,這個是運行期錯誤,程序員必須避免這樣的失誤
這樣的問題在于sp1,sp2,在丟失p的擁有權時釋放相應資源,即會執(zhí)行兩次delete p操作。
不可以對unique_ptr執(zhí)行copy或者assign操作,只能move,將擁有權移交給另一個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構造函數(shù),建立一個empty unique pointer |
unique_ptr up(ptr) | 建立unique pointer令其擁有*ptr |
unique_ptr up(nullptr) | 建立一個empty unique pointer |
unique_ptr up(move(up2)) | 建立一個unique pointer,擁有up2之前擁有的pointer(up2將為empty) |
up.~unique_ptr() | 析構函數(shù),調用deleter |
up=up2 | 賦值(sp將共享sp2的擁有權,放棄其先前索擁有對象的所有權) |
up=move(up2) | move assignment(sp2將擁有權移交給up) |
up=nullptr | 對一個被擁有物調用delete,i并令為空(等價up.reset()) |
up1.swap(up2)==swap(up1,up2) | 交換up1,up2的pointer |
up.reset() | 放棄擁有權,并重新初始化,使它=empty |
up.reset(ptr) | 放棄擁有權,重新初始化(擁有*ptr) |
make_unique(…) | 為一個新對象(以傳入的實參為初值)建立一個unique pointer |
up.get() | 返回存儲的pointer,就是返回原始指針,對該原始指針如果執(zhí)行delete,會異常。 |
*up | 同上 |
up-> | 為擁有物提供成員訪問 |
if(up) | 判斷sp是否empty |
get_deleter(up) | 返回deleter的地址(如果有的話),沒有返回nullptr |
到此這篇關于C++11智能指針unique_ptr用法介紹的文章就介紹到這了,更多相關C++11 unique_ptr智能指針內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++實現(xiàn)LeetCode(159.最多有兩個不同字符的最長子串)
這篇文章主要介紹了C++實現(xiàn)LeetCode(159.最多有兩個不同字符的最長子串),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-07-07