【C++11新特性】 C++11智能指針之 unique_ptr

在前面一篇文章中,我們瞭解了 C++11 中引入的智能指針之一 shared_ptr 和 weak_ptr ,今天,我們來介紹一下另一種智能指針 unique_ptr 。

往期文章參考:

  1. 【C++11新特性】 C++11 智能指針之shared_ptr

  2. 【C++11新特性】 C++11智能指針之weak_ptr

unique_ptr介紹

unique是獨特的、唯一的意思,故名思議,unique_ptr可以“獨佔”地擁有它所指向的對象,它提供一種嚴格意義上的所有權。

這一點和我們前面介紹的 shared_ptr 類型指針有很大的不同:shared_ptr 允許多個指針指向同一對象,而 unique_ptr 在某一時刻只能有一個指針指向該對象。

unique_ptr 保存指向某個對象的指針,當它本身被刪除或者離開其作用域時會自動釋放其指向對象所佔用的資源。

1、如何創建unique_ptr

unique_ptr 不像shared_ptr一樣擁有標準庫函數make_shared來創建一個shared_ptr實例。

要想創建一個 unique_ptr,我們需要將一個 new 操作符返回的指針傳遞給unique_ptr的構造函數。

示例:

int main() {
    // 創建一個unique_ptr實例
    unique_ptr<int> pInt(new int(5));
    cout << *pInt;
}

2、無法進行復制構造和賦值操作

unique_ptr沒有 copy 構造函數,不支持普通的拷貝和賦值操作。

示例:

int main() {
    // 創建一個unique_ptr實例
    unique_ptr<int> pInt(new int(5));
    unique_ptr<int> pInt2(pInt);    // 報錯
    unique_ptr<int> pInt3 = pInt;   // 報錯
}

3、可以進行移動構造和移動賦值操作

unique_ptr雖然沒有支持普通的拷貝和賦值操作,但卻提供了一種移動機制來將指針的所有權從一個unique_ptr轉移給另一個unique_ptr。

如果需要轉移所有權,可以使用std::move()函數。

示例:

int main() {
    unique_ptr<int> pInt(new int(5));
    unique_ptr<int> pInt2 = std::move(pInt);    // 轉移所有權
    //cout << *pInt << endl; // 出錯,pInt爲空
    cout << *pInt2 << endl;
    unique_ptr<int> pInt3(std::move(pInt2));
}

4、可以返回unique_ptr

unique_ptr不支持拷貝操作,但卻有一個例外:可以從函數中返回一個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、爲動態申請的資源提供異常安全保證

我們先來看看下面這一段代碼:

void Func()
{
    int *p = new int(5);

    // ...(可能會拋出異常)

    delete p;
}

這是我們傳統的寫法:當我們動態申請內存後,有可能我們接下來的代碼由於拋出異常或者提前退出(if語句)而沒有執行delete操作。

解決的方法是使用unique_ptr來管理動態內存,只要unique_ptr指針創建成功,其析構函數都會被調用。確保動態資源被釋放。

void Func()
{
    unique_ptr<int> p(new int(5));

    // ...(可能會拋出異常)
}

2、返回函數內動態申請資源的所有權

示例如下:

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;
    // 函數結束後,自動釋放資源
}

3、在容器中保存指針

int main() {
    vector<unique_ptr<int>> vec;
    unique_ptr<int> p(new int(5));
    vec.push_back(std::move(p));    // 使用移動語義
}

4、管理動態數組

標準庫提供了一個可以管理動態數組的unique_ptr版本。

int main() {
    unique_ptr<int[]> p(new int[5] {1, 2, 3, 4, 5});
    p[0] = 0;   // 重載了operator[]
}

作者:Fred^_^

原文:https://blog.csdn.net/Xiejingfa/article/details/50759210

推薦閱讀:

慕課網錄製的視頻上線啦~~~

移動端技術交流喊你入羣啦~~~

推薦幾個堪稱教科書級別的 Android 音視頻入門項目

音視頻面試基礎題

OpenGL 之 GPUImage 源碼分析

覺得不錯,點個在看唄~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章