欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間: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 能夠包裝任意類型,所以,要讓這個類能夠包裝任意類型的指針,我們需要把它變成一個類模板。

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_;
};

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

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

不過,這些問題也相當(dāng)容易解決,加幾個成員函數(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)造和賦值

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

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

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

這里,我們采用移動語義:

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)在它成了移動構(gòu)造函數(shù)。
  • 把賦值函數(shù)中的參數(shù)類型 unique_ptr& 改成了 unique_ptr,在構(gòu)造參數(shù)時直接生成新的智能指針,從而不再需要在函數(shù)體中構(gòu)造臨時對象?,F(xiàn)在賦值函數(shù)的行為是移動還是拷貝,完全依賴于構(gòu)造參數(shù)時走的是移動構(gòu)造還是拷貝構(gòu)造。 根據(jù) C++ 的規(guī)則,如果我提供了移動構(gòu)造函數(shù)而沒有手動提供拷貝構(gòu)造函數(shù),那后者自動被禁用。

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

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

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

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

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

驗(yàn)證

unique_ptr<shape> ptr1{create_shape(shape_type::circle)};
unique_ptr<shape> ptr2{ptr1};             // 編譯出錯
unique_ptr<shape> ptr3;
ptr3 = ptr1;                             // 編譯出錯
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)一個 unique_ptr 相對比較簡單,因?yàn)椴簧婕耙糜?jì)數(shù),只需要一個對象只能被單個 unique_ptr 所擁有。

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

相關(guān)文章

  • C語言實(shí)現(xiàn)打印星號圖案

    C語言實(shí)現(xiàn)打印星號圖案

    這篇文章主要介紹了C語言實(shí)現(xiàn)打印星號圖案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • STL常用算法之排序算法詳解

    STL常用算法之排序算法詳解

    這篇文章主要介紹了STL常用算法之排序算法詳解,STL提供了六大組件,彼此之間可以組合套用,這六大組件分別是:容器、算法、迭代器、仿函數(shù)、適配器、空間配置器,本文主要講算法中的排序算法,需要的朋友可以參考下
    2024-01-01
  • C++ std::function詳解

    C++ std::function詳解

    類模版std::function是一種通用的多態(tài)函數(shù)包裝器std::function的實(shí)例可以對任何可以調(diào)用的目標(biāo)實(shí)體進(jìn)行存儲、復(fù)制、和調(diào)用操作,本文詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-10-10
  • C++實(shí)現(xiàn)堆排序?qū)嵗榻B

    C++實(shí)現(xiàn)堆排序?qū)嵗榻B

    大家好,本篇文章主要講的是C++實(shí)現(xiàn)堆排序?qū)嵗榻B,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 基于C++浮點(diǎn)數(shù)(float、double)類型數(shù)據(jù)比較與轉(zhuǎn)換的詳解

    基于C++浮點(diǎn)數(shù)(float、double)類型數(shù)據(jù)比較與轉(zhuǎn)換的詳解

    本篇文章是對C++中浮點(diǎn)數(shù)(float、double)類型數(shù)據(jù)比較與轉(zhuǎn)換進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 淺談十進(jìn)制小數(shù)和二進(jìn)制小數(shù)之間的轉(zhuǎn)換

    淺談十進(jìn)制小數(shù)和二進(jìn)制小數(shù)之間的轉(zhuǎn)換

    下面小編就為大家?guī)硪黄獪\談十進(jìn)制小數(shù)和二進(jìn)制小數(shù)之間的轉(zhuǎn)換。小編覺得挺不錯的現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • c語言中if語句是怎么變成匯編代碼的詳解

    c語言中if語句是怎么變成匯編代碼的詳解

    if語句是指編程語言,包括c語言、C#、VB、java、匯編語言等,下面這篇文章主要給大家介紹了關(guān)于c語言中if語句是怎么變成匯編代碼的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 下標(biāo)操作符重載模擬多維數(shù)組詳解

    下標(biāo)操作符重載模擬多維數(shù)組詳解

    雖然不能直接實(shí)現(xiàn)一對下標(biāo)操作符重載,但是我們可以間接模擬。思路是這樣的,先通過單下標(biāo)操作返回一個具有下標(biāo)操作能力的左值,對左值進(jìn)行下標(biāo)操作,兩個下標(biāo)操作表達(dá)式聯(lián)立就實(shí)現(xiàn)了雙下標(biāo)操作
    2013-09-09
  • C++實(shí)現(xiàn)地鐵自動售票系統(tǒng)程序設(shè)計(jì)

    C++實(shí)現(xiàn)地鐵自動售票系統(tǒng)程序設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)地鐵自動售票系統(tǒng)程序設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • c++分離講解模板的概念與使用

    c++分離講解模板的概念與使用

    人們需要編寫多個形式和功能都相似的函數(shù),因此有了函數(shù)模板來減少重復(fù)勞動;人們也需要編寫多個形式和功能都相似的類,于是 C++ 引人了類模板的概念,編譯器從類模板可以自動生成多個類,避免了程序員的重復(fù)勞動
    2022-04-04

最新評論