最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中智能指針unique_ptr的實(shí)現(xiàn)詳解

 更新時(shí)間:2024年01月17日 08:10:34   作者:李慕然  
智能指針本質(zhì)上并不神秘,其實(shí)就是?RAII?資源管理功能的自然展現(xiàn)而已,這篇文章主要為大家詳細(xì)介紹了如何實(shí)現(xiàn)?C++中智能指針的?unique_ptr,需要的可以了解下

前言

智能指針本質(zhì)上并不神秘,其實(shí)就是 RAII 資源管理功能的自然展現(xiàn)而已。本文將介紹如何實(shí)現(xiàn) C++中智能指針的 unique_ptr。

實(shí)現(xiàn)過程

首先,unique_ptr 能夠包裝任意類型,所以,要讓這個(gè)類能夠包裝任意類型的指針,我們需要把它變成一個(gè)類模板。

template <typename T>
class unique_ptr {
public:
  explicit unique_ptr(T* ptr = nullptr)
    : ptr_(ptr) {}
  ~unique_ptr()
  {
    delete ptr_;
  }
  T* get() const { return ptr_; }
private:
  T* ptr_;
};

目前這個(gè) unique_ptr 的行為還是和指針有點(diǎn)差異的:

  • 它不能用 * 運(yùn)算符解引用
  • 它不能用 -> 運(yùn)算符指向?qū)ο蟪蓡T
  • 它不能像指針一樣用在布爾表達(dá)式里

不過,這些問題也相當(dāng)容易解決,加幾個(gè)成員函數(shù)就可以:

template <typename T>
class unique_ptr {
public:
  …
  T& operator*() const { return *ptr_; }
  T* operator->() const { return ptr_; }
  operator bool() const { return ptr_; }
}

拷貝構(gòu)造和賦值

最簡(jiǎn)單的情況顯然是禁止拷貝。我們可以使用下面的代碼:

template <typename T>
class unique_ptr {
  …
  unique_ptr(const unique_ptr&) = delete;
  unique_ptr& operator=(const unique_ptr&) = delete;
  …
};

禁用這兩個(gè)函數(shù)非常簡(jiǎn)單,但是,有時(shí)我們需要轉(zhuǎn)移所有權(quán),那么這個(gè)方案就不可行了。

這里,我們采用移動(dòng)語(yǔ)義:

template <typename T>
class unique_ptr {
  …
  unique_ptr(unique_ptr&& other)
  {
    ptr_ = other.release();
  }
  unique_ptr& operator=(unique_ptr rhs)
  {
    rhs.swap(*this);
    return *this;
  }
  …
};
  • 把拷貝構(gòu)造函數(shù)中的參數(shù)類型 unique_ptr& 改成了 unique_ptr&&;現(xiàn)在它成了移動(dòng)構(gòu)造函數(shù)。
  • 把賦值函數(shù)中的參數(shù)類型 unique_ptr& 改成了 unique_ptr,在構(gòu)造參數(shù)時(shí)直接生成新的智能指針,從而不再需要在函數(shù)體中構(gòu)造臨時(shí)對(duì)象。現(xiàn)在賦值函數(shù)的行為是移動(dòng)還是拷貝,完全依賴于構(gòu)造參數(shù)時(shí)走的是移動(dòng)構(gòu)造還是拷貝構(gòu)造。 根據(jù) C++ 的規(guī)則,如果我提供了移動(dòng)構(gòu)造函數(shù)而沒有手動(dòng)提供拷貝構(gòu)造函數(shù),那后者自動(dòng)被禁用。

子類指針向基類指針的轉(zhuǎn)換

一個(gè) circle* 類是可以隱式轉(zhuǎn)換成 shape* 類的,但上面的 unique_ptr<circle> 卻無(wú)法自動(dòng)轉(zhuǎn)換成 unique_ptr<shape>。

不過,只需要額外加一點(diǎn)模板代碼,就能實(shí)現(xiàn)這一行為。在我們目前給出的實(shí)現(xiàn)里,只需要增加一個(gè)構(gòu)造函數(shù)即可。

template <typename U>
unique_ptr(unique_ptr<U>&& other)
{
  ptr_ = other.release();
}

這樣,我們自然而然利用了指針的轉(zhuǎn)換特性:現(xiàn)在 unique_ptr<circle> 可以移動(dòng)給 unique_ptr<shape>,但不能移動(dòng)給 unique_ptr<triangle>。不正確的轉(zhuǎn)換會(huì)在代碼編譯時(shí)直接報(bào)錯(cuò)。

驗(yàn)證

unique_ptr<shape> ptr1{create_shape(shape_type::circle)};
unique_ptr<shape> ptr2{ptr1};             // 編譯出錯(cuò)
unique_ptr<shape> ptr3;
ptr3 = ptr1;                             // 編譯出錯(cuò)
ptr3 = std::move(ptr1);                  // OK,可以
unique_ptr<shape> ptr4{std::move(ptr3)};  // OK,可以

完整代碼

#include <utility>

template <typename T>
class unique_ptr {
public:
  explicit unique_ptr(T* ptr = nullptr)
    : ptr_(ptr) {}
  ~unique_ptr()
  {
    delete ptr_;
  }
  unique_ptr(unique_ptr&& other)
  {
    ptr_ = other.release();
  }
  // 子類指針向基類指針的轉(zhuǎn)換
  template <typename U>
  unique_ptr(unique_ptr<U>&& other)
  {
    ptr_ = other.release();
  }
  unique_ptr& operator=(unique_ptr rhs)
  {
    rhs.swap(*this);
    return *this;
  }
  T* release()
  {
    T* ptr = ptr_;
    ptr_ = nullptr;
    return ptr;
  }
  void swap(unique_ptr& rhs)
  {
    using std::swap;
    swap(ptr_, rhs.ptr_);
  }
  T* get() const { return ptr_; }
  T& operator*() const { return *ptr_; }
  T* operator->() const { return ptr_; }
  operator bool() const { return ptr_; }
private:
  T* ptr_;
};

總結(jié)

自行實(shí)現(xiàn)一個(gè) unique_ptr 相對(duì)比較簡(jiǎn)單,因?yàn)椴簧婕耙糜?jì)數(shù),只需要一個(gè)對(duì)象只能被單個(gè) unique_ptr 所擁有。

以上就是C++中智能指針unique_ptr的實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于C++智能指針unique_ptr的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++項(xiàng)目中后綴名vcxproj和sln的區(qū)別及說(shuō)明

    c++項(xiàng)目中后綴名vcxproj和sln的區(qū)別及說(shuō)明

    這篇文章主要介紹了c++項(xiàng)目中后綴名vcxproj和sln的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • C++中的函數(shù)返回值與拷貝用法

    C++中的函數(shù)返回值與拷貝用法

    這篇文章主要介紹了C++中的函數(shù)返回值與拷貝用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • OpenCV?通過Mat遍歷圖像的方法匯總

    OpenCV?通過Mat遍歷圖像的方法匯總

    對(duì)圖像中的所有點(diǎn)或特殊點(diǎn)進(jìn)行運(yùn)算,所以遍歷圖像就顯得很重要,如何高效的遍歷圖像是一個(gè)很值得探討的問題,本文給大家?guī)?lái)了多種方法操作OpenCV?通過Mat遍歷圖像,感興趣的朋友一起看看吧
    2022-02-02
  • C++ 整型與字符串的互轉(zhuǎn)方式

    C++ 整型與字符串的互轉(zhuǎn)方式

    今天小編就為大家分享一篇C++ 整型與字符串的互轉(zhuǎn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2019-12-12
  • C語(yǔ)言小程序 如何判斷兩個(gè)日期之差

    C語(yǔ)言小程序 如何判斷兩個(gè)日期之差

    輸入兩個(gè)日期,計(jì)算之間相差多少天。 用了兩種方法實(shí)現(xiàn),第二種利用結(jié)構(gòu)體,代碼比較清晰,其余的都一樣
    2013-07-07
  • CRC校驗(yàn)原理及其C語(yǔ)言實(shí)現(xiàn)詳解

    CRC校驗(yàn)原理及其C語(yǔ)言實(shí)現(xiàn)詳解

    循環(huán)冗余校驗(yàn)(Cyclic?Redundancy?Check,?CRC)是一種根據(jù)網(wǎng)絡(luò)數(shù)據(jù)包或計(jì)算機(jī)文件等數(shù)據(jù)產(chǎn)生簡(jiǎn)短固定位數(shù)校驗(yàn)碼的一種信道編碼技術(shù)。本文主要介紹了CRC校驗(yàn)原理及其C語(yǔ)言實(shí)現(xiàn),感興趣的可以了解一下
    2023-03-03
  • C?語(yǔ)言注釋和變量使用基礎(chǔ)詳解

    C?語(yǔ)言注釋和變量使用基礎(chǔ)詳解

    這篇文章主要為大家介紹了C語(yǔ)言注釋和變量使用示例基礎(chǔ)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 老生常談C++ 中的繼承

    老生常談C++ 中的繼承

    這篇文章主要介紹了C++ 中的繼承,本文通過實(shí)例代碼給大家介紹的非常詳細(xì)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • C語(yǔ)言詳解strcmp函數(shù)的分析及實(shí)現(xiàn)

    C語(yǔ)言詳解strcmp函數(shù)的分析及實(shí)現(xiàn)

    strcmp函數(shù)語(yǔ)法為“int strcmp(char *str1,char *str2)”,其作用是比較字符串str1和str2是否相同,如果相同則返回0,如果不同,前者大于后者則返回1,否則返回-1
    2022-05-05
  • C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)詳解小白篇

    C語(yǔ)言編程數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)詳解小白篇

    這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ),非常適合初學(xué)數(shù)據(jù)結(jié)構(gòu)的小白,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-09-09

最新評(píng)論

吴堡县| 西城区| 江口县| 静乐县| 沅江市| 翁源县| 登封市| 鞍山市| 洛浦县| 佛教| 思茅市| 耿马| 九龙坡区| 荔波县| 涟源市| 花垣县| 敖汉旗| 攀枝花市| 平顶山市| 新民市| 紫云| 洛隆县| 偃师市| 教育| 常宁市| 辽中县| 成都市| 乐清市| 武川县| 南江县| 行唐县| 威海市| 大宁县| 霞浦县| 石渠县| 汉沽区| 东乌珠穆沁旗| 万源市| 会宁县| 柳河县| 东山县|