C++11智能指針中的 unique_ptr實例詳解
在前面一篇文章中,我們了解了 C++11 中引入的智能指針之一 shared_ptr 和 weak_ptr ,今天,我們來介紹一下另一種智能指針 unique_ptr 。
往期文章參考:
【C++11新特性】 C++11 智能指針之shared_ptr
unique_ptr介紹
unique是獨特的、唯一的意思,故名思議,unique_ptr可以“獨占”地?fù)碛兴赶虻膶ο螅峁┮环N嚴(yán)格意義上的所有權(quán)。
這一點和我們前面介紹的 shared_ptr 類型指針有很大的不同:shared_ptr 允許多個指針指向同一對象,而 unique_ptr 在某一時刻只能有一個指針指向該對象。
unique_ptr 保存指向某個對象的指針,當(dāng)它本身被刪除或者離開其作用域時會自動釋放其指向?qū)ο笏加玫馁Y源。
1、如何創(chuàng)建unique_ptr
unique_ptr 不像shared_ptr一樣擁有標(biāo)準(zhǔn)庫函數(shù)make_shared來創(chuàng)建一個shared_ptr實例。
要想創(chuàng)建一個 unique_ptr,我們需要將一個 new 操作符返回的指針傳遞給unique_ptr的構(gòu)造函數(shù)。
示例:
int main() {
// 創(chuàng)建一個unique_ptr實例
unique_ptr<int> pInt(new int(5));
cout << *pInt;
}
2、無法進(jìn)行復(fù)制構(gòu)造和賦值操作
unique_ptr沒有 copy 構(gòu)造函數(shù),不支持普通的拷貝和賦值操作。
示例:
int main() {
// 創(chuàng)建一個unique_ptr實例
unique_ptr<int> pInt(new int(5));
unique_ptr<int> pInt2(pInt); // 報錯
unique_ptr<int> pInt3 = pInt; // 報錯
}
3、可以進(jìn)行移動構(gòu)造和移動賦值操作
unique_ptr雖然沒有支持普通的拷貝和賦值操作,但卻提供了一種移動機制來將指針的所有權(quán)從一個unique_ptr轉(zhuǎn)移給另一個unique_ptr。
如果需要轉(zhuǎn)移所有權(quán),可以使用std::move()函數(shù)。
示例:
int main() {
unique_ptr<int> pInt(new int(5));
unique_ptr<int> pInt2 = std::move(pInt); // 轉(zhuǎn)移所有權(quán)
//cout << *pInt << endl; // 出錯,pInt為空
cout << *pInt2 << endl;
unique_ptr<int> pInt3(std::move(pInt2));
}
4、可以返回unique_ptr
unique_ptr不支持拷貝操作,但卻有一個例外:可以從函數(shù)中返回一個unique_ptr。
示例:
unique_ptr<int> clone(int p)
{
unique_ptr<int> pInt(new int(p));
return pInt; // 返回unique_ptr
}
int main() {
int p = 5;
unique_ptr<int> ret = clone(p);
cout << *ret << endl;
}
unique_ptr使用場景
1、為動態(tài)申請的資源提供異常安全保證
我們先來看看下面這一段代碼:
void Func()
{
int *p = new int(5);
// ...(可能會拋出異常)
delete p;
}
這是我們傳統(tǒng)的寫法:當(dāng)我們動態(tài)申請內(nèi)存后,有可能我們接下來的代碼由于拋出異常或者提前退出(if語句)而沒有執(zhí)行delete操作。
解決的方法是使用unique_ptr來管理動態(tài)內(nèi)存,只要unique_ptr指針創(chuàng)建成功,其析構(gòu)函數(shù)都會被調(diào)用。確保動態(tài)資源被釋放。
void Func()
{
unique_ptr<int> p(new int(5));
// ...(可能會拋出異常)
}
2、返回函數(shù)內(nèi)動態(tài)申請資源的所有權(quán)
示例如下:
unique_ptr<int> Func(int p)
{
unique_ptr<int> pInt(new int(p));
return pInt; // 返回unique_ptr
}
int main() {
int p = 5;
unique_ptr<int> ret = Func(p);
cout << *ret << endl;
// 函數(shù)結(jié)束后,自動釋放資源
}
3、在容器中保存指針
int main() {
vector<unique_ptr<int>> vec;
unique_ptr<int> p(new int(5));
vec.push_back(std::move(p)); // 使用移動語義
}
4、管理動態(tài)數(shù)組
標(biāo)準(zhǔn)庫提供了一個可以管理動態(tài)數(shù)組的unique_ptr版本。
int main() {
unique_ptr<int[]> p(new int[5] {1, 2, 3, 4, 5});
p[0] = 0; // 重載了operator[]
}
總結(jié)
到此這篇關(guān)于C++11智能指針中的 unique_ptr實例詳解的文章就介紹到這了,更多相關(guān)C++11智能指針unique_ptr內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用C++和Crypto++庫實現(xiàn)AES加密與解密
在這篇博客中,我們將深入探討如何利用C++和Crypto++庫實現(xiàn)高效且安全的AES加密與解密機制,Crypto++是一款高度認(rèn)可的免費C++類庫,文中通過代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2024-01-01
Qt私有信號實現(xiàn)(private signal)
在使用Qt信號槽機制的時候,有時候我們需要一個信號只能由類內(nèi)發(fā)出,而不允許使用該類對象的用戶發(fā)出,此時就需要私有信號的支持,本文主要介紹了Qt私有信號實現(xiàn)(private signal),感興趣的可以了解一下2023-10-10
用c++實現(xiàn)將文本每個單詞首字母轉(zhuǎn)換為大寫
本篇文章是對用c++實現(xiàn)將文本每個單詞首字母轉(zhuǎn)換為大寫的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C語言超詳細(xì)講解數(shù)據(jù)結(jié)構(gòu)中雙向帶頭循環(huán)鏈表
帶頭雙向循環(huán)鏈表:結(jié)構(gòu)最復(fù)雜,一般用在單獨存儲數(shù)據(jù)。實際中使用的鏈表數(shù)據(jù)結(jié)構(gòu),都是帶頭雙向循環(huán)鏈表。另外這個結(jié)構(gòu)雖然結(jié)構(gòu)復(fù)雜,但是使用代碼實現(xiàn)以后會發(fā)現(xiàn)結(jié)構(gòu)會帶來很多優(yōu)勢,實現(xiàn)反而簡單2022-04-04

