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

C++簡(jiǎn)單實(shí)現(xiàn)shared_ptr的代碼

 更新時(shí)間:2022年09月29日 09:59:26   作者:夢(mèng)想是優(yōu)秀社畜  
智能指針用于資源管理,為了保證資源的操作得到順利的執(zhí)行防止資源泄露,因此大多數(shù)實(shí)現(xiàn)都以noexcept在參數(shù)列表后聲明為不拋出異常,這篇文章主要介紹了C++簡(jiǎn)單實(shí)現(xiàn)shared_ptr的代碼,需要的朋友可以參考下

一、一些說(shuō)明

1.智能指針用于資源管理,為了保證資源的操作得到順利的執(zhí)行防止資源泄露,因此大多數(shù)實(shí)現(xiàn)都以noexcept在參數(shù)列表后聲明為不拋出異常。

2.對(duì)于有些明確不需要更改調(diào)用對(duì)象內(nèi)容的成員函數(shù),用const在參數(shù)列表后修飾,常量成員函數(shù)不能改變調(diào)用它的對(duì)象的內(nèi)容。

3.在用原始指針構(gòu)造智能指針的參數(shù)構(gòu)造前用explicit聲明,防止隱式的轉(zhuǎn)化。

3.swap函數(shù)內(nèi)部調(diào)用標(biāo)準(zhǔn)命名空間的swap()函數(shù),必須以std::顯示指定是標(biāo)準(zhǔn)命名空間

4.做筆記使用,如果有不足或者錯(cuò)誤的地方還請(qǐng)補(bǔ)充或者指正!!多謝!??!

二、基本的構(gòu)造和析構(gòu)成分

SharedPtr()noexcept = default // 默認(rèn)構(gòu)造
explicit SharedPtr(T* ptr) noexcept // 參數(shù)構(gòu)造
SharedPtr(const SharedPtr& ptr)noexcept // 拷貝構(gòu)造
SharedPtr(SharedPtr&& ptr)noexcept // 移動(dòng)構(gòu)造
~SharedPtr() noexcept // 析構(gòu)函數(shù)

三、運(yùn)算符重載

SharedPtr& operator=(const SharedPtr& rhs)noexcept  // 拷貝賦值運(yùn)算符重載
SharedPtr& operator=(SharedPtr&& rhs)noexcept  // 移動(dòng)賦值運(yùn)算符重載
T& operator->() const noexcept // 指針運(yùn)算符重載
T& operator*() const noexcept // 解引用運(yùn)算符重載

四、實(shí)現(xiàn)的shared_ptr函數(shù)接口

T* get() const noexcept // 獲取原始指針對(duì)象
int use_count() const noexcept // 獲取引用計(jì)數(shù)
void reset()noexcept // 重置指針
bool unique() noexcept // 判斷是否只有一個(gè)使用者
void swap() noexcept // 交換對(duì)象內(nèi)容

五、CPP代碼

#include<iostream>
using namespace std;
 
// 引用計(jì)數(shù)類
class RefCount {
private:
	int count{1};
public:
	int use_count() const noexcept { return count; }
	void dec_count()noexcept { --count; }
	void inc_count()noexcept { ++count; }
};
 
// shared_ptr類模板
template<class T>
class SharedPtr {
private:
	T* origin_ptr{ nullptr }; // 原始指針
	RefCount* refCount{ nullptr }; // 引用計(jì)數(shù)
public:
	SharedPtr()noexcept = default; // 默認(rèn)構(gòu)造
	SharedPtr(nullptr_t)noexcept :SharedPtr() {} // 空指針構(gòu)造
	explicit SharedPtr(T* ptr)noexcept :origin_ptr(ptr), refCount(nullptr){ // 用原始指針作為參數(shù)構(gòu)造
		if (origin_ptr != nullptr) refCount = new RefCount();
	}
	SharedPtr(const SharedPtr& ptr)noexcept :origin_ptr(ptr.origin_ptr), refCount(ptr.refCount) { // 拷貝構(gòu)造
		if(origin_ptr != nullptr) refCount->inc_count();
	}
	SharedPtr(SharedPtr&& ptr)noexcept :origin_ptr(ptr.origin_ptr), refCount(ptr.refCount) { // 移動(dòng)構(gòu)造
		ptr.origin_ptr = nullptr;
		ptr.refCount = nullptr;
	}
	~SharedPtr()noexcept { // 析構(gòu)函數(shù)
		if (origin_ptr != nullptr && refCount->use_count() == 0) {
			delete origin_ptr;
			delete refCount;
			origin_ptr = nullptr;
			refCount = nullptr;
		}
	}
	SharedPtr& operator=(const SharedPtr& rhs)noexcept { // 拷貝賦值運(yùn)算符重載
		SharedPtr(rhs).swap(*this);
		return *this;
	}
	SharedPtr& operator=(SharedPtr&& rhs)noexcept { // 移動(dòng)賦值運(yùn)算符重載
		SharedPtr(move(rhs)).swap(*this);
		return *this;
	}
	T& operator->() const noexcept{ // 指針運(yùn)算符重載
		return origin_ptr;
	}
	T& operator*() const noexcept { // 解引用運(yùn)算符重載
		return *origin_ptr;
	}
 
public: // 以下是提供的接口函數(shù)
	T* get()const noexcept { // get()函數(shù)獲取原始指針對(duì)象
		return origin_ptr;
	}
	int use_count() const noexcept { // use_count()函數(shù)獲取引用計(jì)數(shù)
		return origin_ptr == nullptr ? 0 : refCount->use_count();
	}
	void reset()noexcept { // reset()重置指針
		SharedPtr().swap(*this);
	}
	void reset(nullptr_t) noexcept {
		reset();
	}
	void reset(T* ptr)noexcept {
		SharedPtr(ptr).swap(*this);
	}
	bool unique()noexcept { // unique() 查看是否資源獨(dú)有
		return refCount == nullptr ? false : (refCount->use_count() == 1);
	}
	void swap(SharedPtr& rhs) noexcept{ // swap()交換對(duì)象內(nèi)容
		std::swap(origin_ptr, rhs.origin_ptr); // 這里必須顯示指定是std命名空間!
		std::swap(refCount, rhs.refCount);
	}
};
int main() {
	int* a = new int(2);
	SharedPtr<int>p(a); //測(cè)試構(gòu)造函數(shù)
	cout << p.use_count() << endl;
	cout << *p << endl;
	SharedPtr<int>q(p); //測(cè)試拷貝構(gòu)造
	cout << p.use_count() << endl;
	cout << q.use_count() << endl;
	SharedPtr<int>n = p; //測(cè)試賦值運(yùn)算符
	cout << p.use_count() << endl;
	cout << n.use_count() << endl;
	SharedPtr<int>m = move(p); //測(cè)試右值引用賦值運(yùn)算符
	cout << q.use_count() << endl;
	// cout << p.get_count() << endl;
	q.reset();
	cout << q.get() << endl;
	return 0;
}

C++ 簡(jiǎn)單實(shí)現(xiàn)shared_ptr

共享指針

管理指針的存儲(chǔ),提供有限的垃圾回收工具,并可能與其他對(duì)象共享該管理。

shared_ptr類型的對(duì)象都能夠獲得指針的所有權(quán)并共享該所有權(quán):一旦它們獲得所有權(quán),當(dāng)最后一個(gè)所有者釋放該所有權(quán)時(shí),指針的所有者組就負(fù)責(zé)刪除該所有者。

shared_ptr對(duì)象在自身被銷毀后,或者一旦其值因賦值操作或顯式調(diào)用 shared_ptr::reset 而發(fā)生更改,就會(huì)釋放其共同擁有的對(duì)象的所有權(quán)。一旦通過(guò)指針共享所有權(quán)的所有shared_ptr對(duì)象都釋放了此所有權(quán),則將刪除托管對(duì)象(通常通過(guò)調(diào)用 ::delete,但在構(gòu)造時(shí)可能會(huì)指定不同的刪除程序)。

shared_ptr對(duì)象只能通過(guò)復(fù)制其值來(lái)共享所有權(quán):如果從同一個(gè)(非shared_ptr)指針構(gòu)造(或創(chuàng)建)兩個(gè)shared_ptr,則它們都將擁有該指針而不共享它,當(dāng)其中一個(gè)對(duì)象釋放它(刪除其托管對(duì)象)并使另一個(gè)指向無(wú)效位置時(shí),會(huì)導(dǎo)致潛在的訪問(wèn)問(wèn)題。

此外,shared_ptr對(duì)象可以通過(guò)指針共享所有權(quán),同時(shí)指向另一個(gè)對(duì)象。此功能稱為別名,通常用于指向成員對(duì)象,同時(shí)擁有它們所屬的對(duì)象。因此,shared_ptr可能與兩個(gè)指針相關(guān):

  • 存儲(chǔ)的指針,它是它所指向的指針,也是它使用運(yùn)算符* 取消引用的指針。
  • 擁有的指針(可能是共享的),這是所有權(quán)組負(fù)責(zé)在某個(gè)時(shí)刻刪除的指針,并且它被視為一種用途。

通常,存儲(chǔ)的指針和擁有的指針引用同一對(duì)象,但別名shared_ptr對(duì)象(使用別名構(gòu)造函數(shù)及其副本構(gòu)造的對(duì)象)可能引用不同的對(duì)象。

不擁有任何指針的shared_ptr稱為空shared_ptr。不指向任何對(duì)象的shared_ptr稱為 null shared_ptr,不應(yīng)取消引用。請(qǐng)注意,空shared_ptr不一定是 null shared_ptr,null shared_ptr不一定是空shared_ptr。

shared_ptr對(duì)象通過(guò)運(yùn)算符 * 和 -> 提供對(duì)它們所指向的對(duì)象的訪問(wèn),從而復(fù)制有限的指針功能。出于安全原因,它們不支持指針?biāo)阈g(shù)。

相關(guān)類weak_ptr能夠與shared_ptr對(duì)象共享指針,而無(wú)需擁有它們。

成員函數(shù)

	(構(gòu)造函數(shù))構(gòu)造shared_ptr(公共成員函數(shù))
	(析構(gòu)函數(shù))銷毀shared_ptr(公共成員函數(shù))
	operator=	shared_ptr賦值(公共成員函數(shù))
	swap	交換內(nèi)容(公共成員函數(shù))
	reset	重置指針(公共成員函數(shù))
	get	獲取指針(公共成員函數(shù))
	operator*	取消引用對(duì)象(公共成員函數(shù))
	operator->	取消引用對(duì)象成員(公共成員函數(shù))
	operator[]  (C++17)提供到被存儲(chǔ)數(shù)組的帶下標(biāo)訪問(wèn)(公開成員函數(shù))
	use_count	返回計(jì)數(shù)(公共成員函數(shù))
	unique(C++20前)	檢查是否唯一(公共成員函數(shù))
	operator bool	檢查是否不為空(公共成員函數(shù))
	owner_before	基于所有者的共享指針排序(公共成員函數(shù)模板)

非成員函數(shù)
	swap	交換shared_ptr對(duì)象的內(nèi)容(函數(shù)模板)
	relational operators	關(guān)系運(yùn)算符 ==, !=, <, <=, >, >= (函數(shù)模板 )
	ostream operator<<	將存儲(chǔ)的指針的值輸出到輸出流(函數(shù)模板)

具體功能:
	make_shared,make_shared_for_overwrite(C++20)	創(chuàng)建管理一個(gè)新對(duì)象的共享指針(函數(shù)模板)
	allocate_shared,allocate_shared_for_overwrite(C++20)	創(chuàng)建管理一個(gè)用分配器分配的新對(duì)象的共享指針(函數(shù)模板)
	static_pointer_cast,dynamic_pointer_cast,const_pointer_cast,reinterpret_pointer_cast    (C++17)應(yīng)用 static_cast、dynamic_cast、const_cast 或 reinterpret_cast 到被存儲(chǔ)指針(函數(shù)模板)
	get_deleter	返回指定類型中的刪除器,若其擁有(函數(shù)模板)

cpp

#include <utility>
#include <cstddef>

class ref_count
{
public:
    int use_count() const noexcept { return count_; }
    void inc_ref() noexcept { ++count_; }
    int dec_ref() noexcept { return --count_; }

private:
    int count_{1};
};

template <typename T>
class Shared_ptr
{
public:
    constexpr Shared_ptr() noexcept = default;
    constexpr Shared_ptr(nullptr_t) noexcept : Shared_ptr() {}
    explicit Shared_ptr(T *ptr) : ptr_{ptr}
    {
        if (ptr_ != nullptr)
        {
            rep_ = new ref_count{};
        }
    }
    Shared_ptr(const Shared_ptr &rhs) noexcept : ptr_{rhs.ptr_}, rep_{rhs.rep_}
    {
        if (ptr_ != nullptr)
        {
            rep_->inc_ref();
        }
    }
    Shared_ptr(Shared_ptr &&rhs) noexcept : ptr_{rhs.ptr_}, rep_{rhs.rep_}
    {
        rhs.ptr_ = nullptr;
        rhs.rep_ = nullptr;
    }
    ~Shared_ptr() noexcept
    {
        if (rep_ != nullptr && rep_->dec_ref() == 0)
        {
            delete ptr_;
            delete rep_;
        }
    }

    Shared_ptr &operator=(const Shared_ptr &rhs)
    {
        Shared_ptr{rhs}.swap(*this);
        return *this;
    }
    Shared_ptr &operator=(Shared_ptr &&rhs)
    {
        Shared_ptr{std::move(rhs)}.swap(*this);
        return *this;
    }
    void reset() noexcept
    {
        Shared_ptr{}.swap(*this);
    }
    void reset(nullptr_t) noexcept
    {
        reset();
    }
    void reset(T *ptr)
    {
        Shared_ptr{ptr}.swap(*this);
    }

    void swap(Shared_ptr &rhs) noexcept
    {
        std::swap(ptr_, rhs.ptr_);
        std::swap(rep_, rhs.rep_);
    }
    T *get() const noexcept
    {
        return ptr_;
    }

    long use_count() const noexcept
    {
        return rep_ == nullptr ? 0 : rep_->use_count();
    }
    bool unique() const noexcept
    {
        return rep_->use_count() == 1;
    }

    T &operator*() const noexcept
    {
        return *ptr_;
    }
    T &operator->() const noexcept
    {
        return ptr_;
    }

    explicit operator bool() const noexcept
    {
        return static_cast<bool>(ptr_);
    }

private:
    T *ptr_{nullptr};
    ref_count *rep_{nullptr};
};

template <typename T, typename... Args>
auto make_Shared(Args &&...args)
{
    return Shared_ptr<T>{new T(std::forward(args)...)};
}

到此這篇關(guān)于C++ shared_ptr實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++ shared_ptr實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C++中多態(tài)的底層原理

    詳解C++中多態(tài)的底層原理

    要了解C++多態(tài)的底層原理需要我們對(duì)C指針有著深入的了解,這個(gè)在打印虛表的時(shí)候就可以見(jiàn)功底,所以快來(lái)跟隨小編一起學(xué)習(xí)一下吧
    2022-04-04
  • 一篇文章帶你了解C語(yǔ)言指針進(jìn)階

    一篇文章帶你了解C語(yǔ)言指針進(jìn)階

    這篇文章主要介紹了C語(yǔ)言指針詳解及用法示例,介紹了其相關(guān)概念,然后分享了幾種用法,具有一定參考價(jià)值。需要的朋友可以了解下
    2021-09-09
  • CrashRpt使用案例詳解

    CrashRpt使用案例詳解

    這篇文章主要介紹了CrashRpt使用案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 詳解QT使用QtGui顯示QImage的幾種方法

    詳解QT使用QtGui顯示QImage的幾種方法

    本文主要介紹了QT使用QtGui顯示QImage的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)版通訊錄的代碼分享

    C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)版通訊錄的代碼分享

    這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的動(dòng)態(tài)版通訊錄,主要運(yùn)用了結(jié)構(gòu)體,一維數(shù)組,函數(shù),分支與循環(huán)語(yǔ)句等等知識(shí),需要的可以參考一下
    2023-01-01
  • 淺談C/C++中的static與extern關(guān)鍵字的使用詳解

    淺談C/C++中的static與extern關(guān)鍵字的使用詳解

    本篇文章是對(duì)C/C++中的static與extern關(guān)鍵字的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++讀寫ini配置文件實(shí)現(xiàn)過(guò)程詳解

    C++讀寫ini配置文件實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了C++讀寫ini配置文件實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • C++直接cout指針名的含義?

    C++直接cout指針名的含義?

    今天小編就為大家分享一篇關(guān)于C++直接cout指針名的含義?,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • VS Code 中搭建 Qt 開發(fā)環(huán)境方案分享

    VS Code 中搭建 Qt 開發(fā)環(huán)境方案分享

    這篇文章主要介紹了VS Code 中搭建 Qt 開發(fā)環(huán)境方案分享的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • C++ STL vector的模擬實(shí)現(xiàn)

    C++ STL vector的模擬實(shí)現(xiàn)

    這篇文章主要介紹了C++ STL vector的模擬實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評(píng)論

正镶白旗| 大庆市| 卢湾区| 健康| 慈溪市| 丰城市| 长寿区| 阿拉尔市| 渝北区| 通州区| 裕民县| 石首市| 兴城市| 冕宁县| 南召县| 沁水县| 青川县| 牙克石市| 宝应县| 长沙市| 瓮安县| 宜城市| 营山县| 宣化县| 宜兴市| 无棣县| 双桥区| 靖远县| 集贤县| 建德市| 武穴市| 舞钢市| 建阳市| 蓝山县| 永修县| 郑州市| 永康市| 宽甸| 延庆县| 华坪县| 措勤县|