国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++入門到精通】智能指針 shared_ptr 簡介及C++模擬實現(xiàn) [ C++入門 ]

這篇具有很好參考價值的文章主要介紹了【C++入門到精通】智能指針 shared_ptr 簡介及C++模擬實現(xiàn) [ C++入門 ]。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【C++入門到精通】智能指針 shared_ptr 簡介及C++模擬實現(xiàn) [ C++入門 ],C++,c++,java,開發(fā)語言

引言

在 C++ 動態(tài)內(nèi)存管理中,除了 auto_ptrunique_ptr 之外,還有一種智能指針 shared_ptr,它可以讓多個指針共享同一個動態(tài)資源,并且能夠自動釋放資源。shared_ptr 通過引用計數(shù)的方式來管理內(nèi)存,能夠避免程序中出現(xiàn)懸空指針和內(nèi)存泄漏等問題。本文將介紹 shared_ptr 的簡介和使用方法,并提供一個 C++ 模擬實現(xiàn),以幫助讀者更好地理解其原理和實現(xiàn)。

一、簡介

std::shared_ptr 是 C++11 標準庫中的一個智能指針,它可以讓多個指針共享同一個動態(tài)資源,并且能夠自動釋放資源。shared_ptr 通過引用計數(shù)的方式來管理內(nèi)存,能夠避免程序中出現(xiàn)懸空指針和內(nèi)存泄漏等問題

std::auto_ptrstd::unique_ptr 不同,std::shared_ptr 可以被多個指針所共享。當一個 shared_ptr 被賦值給另一個 shared_ptr 或者被拷貝構(gòu)造時,它所管理的資源的引用計數(shù)會增加。只有在最后一個shared_ptr 被銷毀時,才會釋放所管理的資源。這種語義被稱為“共享所有權(quán)”。

??std::shared_ptr官方文檔

【C++入門到精通】智能指針 shared_ptr 簡介及C++模擬實現(xiàn) [ C++入門 ],C++,c++,java,開發(fā)語言

二、成員函數(shù)

?為了方便用戶使用 shared_ptr 智能指針,shared_ptr<T> 模板類還提供有一些實用的成員方法,它們各自的功能如下表所示

成員方法名 功能
operator=() 重載賦值號,使得同一類型的 shared_ptr 智能指針可以相互賦值。
operator * () 重載 * 號,獲取當前 shared_ptr 智能指針對象指向的數(shù)據(jù)。
operator->() 重載 -> 號,當智能指針指向的數(shù)據(jù)類型為自定義的結(jié)構(gòu)體時,通過 -> 運算符可以獲取其內(nèi)部的指定成員。
swap() 交換 2 個相同類型 shared_ptr 智能指針的內(nèi)容。
reset() 當函數(shù)沒有實參時,該函數(shù)會使當前 shared_ptr 所指堆內(nèi)存的引用計數(shù)減 1,同時將當前對象重置為一個空指針;當為函數(shù)傳遞一個新申請的堆內(nèi)存時,則調(diào)用該函數(shù)的 shared_ptr 對象會獲得該存儲空間的所有權(quán),并且引用計數(shù)的初始值為 1。
get() 獲得 shared_ptr 對象內(nèi)部包含的普通指針。
use_count() 返回同當前 shared_ptr 對象(包括它)指向相同的所有 shared_ptr 對象的數(shù)量。
unique() 判斷當前 shared_ptr 對象指向的堆內(nèi)存,是否不再有其它 shared_ptr 對象再指向它。
operator bool() 判斷當前 shared_ptr 對象是否為空智能指針,如果是空指針,返回 false;反之,返回 true。

?當然除此之外,C++11 標準還支持同一類型的 shared_ptr 對象,或者 shared_ptrnullptr 之間,進行 ==,!=<,<=,>,>= 運算。

三、使用示例

下面是一個使用 std::shared_ptr 的示例:

#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> sp1(new int(42)); // 創(chuàng)建一個指向整數(shù) 42 的 shared_ptr
    std::shared_ptr<int> sp2 = sp1; // sp2 和 sp1 現(xiàn)在都指向同一個對象
    std::cout << *sp1 << " " << *sp2 << std::endl; // 輸出結(jié)果為 42 42
    *sp1 = 10;
    std::cout << *sp1 << " " << *sp2 << std::endl; // 輸出結(jié)果為 10 10
    sp1.reset(); // 釋放 sp1 的所有權(quán)
    std::cout << *sp2 << std::endl; // 輸出結(jié)果為 10
    sp2.reset(); // 釋放 sp2 的所有權(quán)
    return 0;
}

在這個示例中,我們首先創(chuàng)建了一個指向整數(shù) 42 的 shared_ptr,然后將其賦值給另一個 shared_ptr。由于共享所有權(quán)的語義,它們都指向同一個對象。接著,我們修改了 sp1 指向的對象的值,然后釋放了 sp1 的所有權(quán),此時 sp2 仍然可以訪問該對象。最后,我們釋放了 sp2 的所有權(quán),整個示例結(jié)束。

四、C++模擬實現(xiàn)

#include <iostream>
#include <mutex>

using namespace std;

template<class T>
class shared_ptr
{
public:
    // 構(gòu)造函數(shù)
    explicit shared_ptr(T* ptr = nullptr)
        : _ptr(ptr)
        , _pcount(new int(1))
        , _pmtx(new mutex)
    {}

    // 析構(gòu)函數(shù)
    ~shared_ptr()
    {
        Release();
    }

    /* 釋放資源
    Release() 方法減少引用計數(shù),并根據(jù)引用計數(shù)的值來判斷是否需要刪除指向的堆內(nèi)存對象和引用計數(shù)對象。
    在操作之前,我們使用互斥量 _pmtx 進行加鎖,以保證線程安全。*/
    void Release()
	{
		_pmtx->lock();
		bool deleteFlag = false;
		if (--(*_pcount) == 0)
		{
			if (_ptr)
			{
				// 刪除器進行刪除
				_del(_ptr);
			}

			delete _pcount;
			deleteFlag = true;
		}
		_pmtx->unlock();
		if (deleteFlag)
		{
			delete _pmtx;
		}
	}

    // 增加引用計數(shù)
    void AddCount()
    {
        _pmtx->lock();
        ++(*_pcount);
        _pmtx->unlock();
    }

    // 拷貝構(gòu)造函數(shù)
    shared_ptr(const shared_ptr<T>& sp)
        : _ptr(sp._ptr)
        , _pcount(sp._pcount)
        , _pmtx(sp._pmtx)
    {
        AddCount();
    }

    // 賦值運算符重載
    shared_ptr<T>& operator=(const shared_ptr<T>& sp)
    {
        if (_ptr != sp._ptr)
        {
            Release();

            _ptr = sp._ptr;
            _pcount = sp._pcount;
            _pmtx = sp._pmtx;

            AddCount();
        }

        return *this;
    }

    // operator*() 重載
    T& operator*()
    {
        return *_ptr;
    }

    // operator->() 重載
    T* operator->()
    {
        return _ptr;
    }

    // get() 方法
    T* get()
    {
        return _ptr;
    }

    // use_count() 方法
    int use_count()
    {
        return *_pcount;
    }

    // swap() 方法,交換 2 個 shared_ptr 智能指針的內(nèi)容
    void swap(shared_ptr<T>& sp) noexcept
    {
        std::swap(_ptr, sp._ptr);
        std::swap(_pcount, sp._pcount);
        std::swap(_pmtx, sp._pmtx);
    }

    // reset() 方法,重置 shared_ptr 智能指針對象
    void reset(T* ptr = nullptr)
    {
        // 釋放原有資源
        Release();

        // 重新賦值
        _ptr = ptr;
        _pcount = new int(1);
        _pmtx = new mutex;
    }

private:
    T* _ptr;           // 指向堆內(nèi)存對象的指針
    int* _pcount;      // 引用計數(shù)的指針
    mutex* _pmtx;      // 保護引用計數(shù)的互斥量
    
    // 包裝器
	function<void(T*)> _del = [](T* ptr)
	{
		cout << "lambda delete:" << ptr << endl;
		delete ptr; 
	};
};

以上代碼是一個簡化版的 shared_ptr 智能指針模板類的實現(xiàn)。智能指針是 C++ 中的一個重要工具,可以幫助開發(fā)者更方便地管理動態(tài)內(nèi)存。在手動管理內(nèi)存時,很容易出現(xiàn)內(nèi)存泄漏和懸垂指針等問題,而使用智能指針則可以自動管理對象的生命周期,避免這些問題。

shared_ptr 類實現(xiàn)了一個引用計數(shù)機制,它通過維護一個引用計數(shù),來判斷指向的堆內(nèi)存對象是否應(yīng)該被釋放。當有多個 shared_ptr 指向同一個堆內(nèi)存對象時,引用計數(shù)會增加;當 shared_ptr 對象銷毀時,引用計數(shù)會減少。當引用計數(shù)為 0 時,就可以釋放堆內(nèi)存對象了。

????注意shared_ptr 類是一個簡化版實現(xiàn),可能存在一些問題,不適用于生產(chǎn)環(huán)境中。在實際開發(fā)中,我們可以使用標準庫中的 shared_ptr 類或其他第三方庫中的智能指針實現(xiàn)。

五、std::shared_ptr的線程安全問題

標準庫中的 std::shared_ptr 是線程安全的,可以在多線程環(huán)境下使用。它通過使用原子操作和引用計數(shù)來實現(xiàn)線程安全。

std::shared_ptr 內(nèi)部,引用計數(shù)是一個原子操作,確保多個線程可以安全地對其進行增加和減少操作。當有一個新的 std::shared_ptr 指向同一塊堆內(nèi)存時,引用計數(shù)會增加;當某個 std::shared_ptr 對象銷毀時,引用計數(shù)會減少。只有當引用計數(shù)為 0 時,才會釋放堆內(nèi)存。

此外,std::shared_ptr 還使用了原子操作來保證多個線程之間對智能指針對象的訪問是互斥的。這意味著,在多線程環(huán)境下,不同的線程可以同時拷貝和賦值 std::shared_ptr 對象,而不會出現(xiàn)數(shù)據(jù)競爭的問題。

????注意:雖然 std::shared_ptr 提供了線程安全的引用計數(shù)和訪問控制,但它本身并不保證所指向的對象是線程安全的。如果多個線程同時訪問和修改同一塊內(nèi)存,則需要額外的同步機制來確保線程安全性。

六、總結(jié)

shared_ptr 是C++中的智能指針類,通過引用計數(shù)機制管理堆內(nèi)存對象的生命周期,并使用原子操作確保引用計數(shù)的線程安全性。它支持拷貝構(gòu)造和賦值運算符重載,可以安全地共享指向同一塊堆內(nèi)存的對象。此外,shared_ptr提供了方便的訪問和操作接口,是一種方便而安全的資源管理工具。

當然,從上述方面來看,shared_ptr 確實是一種非常強大的工具。然而,它也存在一個缺點,即“循環(huán)引用問題”。在下一篇文章中,我將介紹與之相關(guān)的知識點——weak_ptr。weak_ptr 是一種特殊的智能指針,用于解決 shared_ptr 循環(huán)引用可能導(dǎo)致的內(nèi)存泄漏問題。通過引入weak_ptr,我們可以打破循環(huán)引用,避免內(nèi)存泄漏,并在需要時安全地訪問對象。敬請期待下一篇文章的發(fā)布!

溫馨提示

感謝您對博主文章的關(guān)注與支持!另外,我計劃在未來的更新中持續(xù)探討與本文相關(guān)的內(nèi)容,會為您帶來更多關(guān)于C++以及編程技術(shù)問題的深入解析、應(yīng)用案例和趣味玩法等。請繼續(xù)關(guān)注博主的更新,不要錯過任何精彩內(nèi)容!

再次感謝您的支持和關(guān)注。期待與您建立更緊密的互動,共同探索C++、算法和編程的奧秘。祝您生活愉快,排便順暢!
【C++入門到精通】智能指針 shared_ptr 簡介及C++模擬實現(xiàn) [ C++入門 ],C++,c++,java,開發(fā)語言文章來源地址http://www.zghlxwxcb.cn/news/detail-813307.html

到了這里,關(guān)于【C++入門到精通】智能指針 shared_ptr 簡介及C++模擬實現(xiàn) [ C++入門 ]的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C++之weak_ptr與shared_ptr智能指針實例(一百九十五)

    C++之weak_ptr與shared_ptr智能指針實例(一百九十五)

    簡介: CSDN博客專家,專注Android/Linux系統(tǒng),分享多mic語音方案、音視頻、編解碼等技術(shù),與大家一起成長! 優(yōu)質(zhì)專欄: Audio工程師進階系列 【 原創(chuàng)干貨持續(xù)更新中…… 】?? 人生格言: 人生從來沒有捷徑,只有行動才是治療恐懼和懶惰的唯一良藥. 更多原創(chuàng),歡迎關(guān)注:An

    2024年02月09日
    瀏覽(24)
  • 智能指針shared_ptr

    shared_ptr共享它指向的對象,內(nèi)部采用計數(shù)機制來實現(xiàn)。當新的shared_ptr與對象關(guān)聯(lián)時,引用計數(shù)加1;當shared_ptr超出作用域時,引用計數(shù)減1;當引用計數(shù)為0時,釋放該對象; shared_ptrA p0 = std::make_sharedA(\\\"西紅柿\\\");//C++11提供 重載了*和-操作符,可以像使用指針一樣使用shared_ptr

    2023年04月23日
    瀏覽(33)
  • 【C++入門到精通】智能指針 auto_ptr、unique_ptr簡介及C++模擬實現(xiàn) [ C++入門 ]

    【C++入門到精通】智能指針 auto_ptr、unique_ptr簡介及C++模擬實現(xiàn) [ C++入門 ]

    在 C++ 中,智能指針是一種非常重要的概念,它能夠幫助我們自動管理動態(tài)分配的內(nèi)存,避免出現(xiàn)內(nèi)存泄漏等問題。在上一篇文章中,我們了解了智能指針的基本概念和原理, 本篇文章將繼續(xù)介紹 auto_ptr 和 unique_ptr 兩種智能指針的概念及其在 C++ 中的模擬實現(xiàn) 。通過學(xué)習(xí)這些

    2024年01月19日
    瀏覽(26)
  • C++11 新特性 ⑥ | 智能指針 unique_ptr、shared_ptr 和 weak_ptr

    目錄 1、引言 2、unique_ptr 3、shared_ptr 4、weak_ptr 5、shared_ptr循環(huán)引用問題(面試題)

    2024年02月09日
    瀏覽(27)
  • C++11中的智能指針unique_ptr、shared_ptr和weak_ptr詳解

    C++11中的智能指針unique_ptr、shared_ptr和weak_ptr詳解

    目錄 1、引言 2、什么是智能指針? 3、在Visual Studio中查看智能指針的源碼實現(xiàn) 4、獨占式指針unique_ptr 4.1、查看unique_ptr的源碼實現(xiàn)片段 4.2、為什么unique_ptr的拷貝構(gòu)造函數(shù)和復(fù)制函數(shù)被delete了?(面試題) 4.3、使用unique_ptr獨占式智能指針的實例 5、共享式指針shared_ptr? 5.1、查

    2024年02月08日
    瀏覽(19)
  • 深入理解和應(yīng)用C++ std::shared_ptr別名構(gòu)造函數(shù)

    在現(xiàn)代C++中,智能指針是一個極為重要的工具,尤其std::shared_ptr以其自動內(nèi)存管理、引用計數(shù)和多線程安全性等特性深受開發(fā)者喜愛。其中一個不太常用但功能強大的構(gòu)造方式是 別名構(gòu)造函數(shù) ,它允許我們創(chuàng)建一個共享相同底層對象但是指向其內(nèi)部不同數(shù)據(jù)成員或子對象的

    2024年01月16日
    瀏覽(31)
  • shared_ptr和unique_ptr主動釋放

    shared_ptr和unique_ptr均可以采用reset()來進行釋放,unique_ptr調(diào)用了reset之后就會直接釋放掉,shared_ptr則會在所有引用計數(shù)變?yōu)?的時候才會釋放申請的內(nèi)存。 注意unique_ptr的release()方法,并不會釋放資源,只會把unique_ptr置為空指針,原來那個資源可以繼續(xù)調(diào)用 reset 結(jié)果: 在reset之

    2024年02月14日
    瀏覽(19)
  • 論 shared_ptr的線程安全

    今天有同事問我shared_ptr是線程更安全的嗎?我當時腦子一懵,有點不確定。 但回過神來仔細一想這什么鳥問題,c++ stl里有線程安全的嗎,shared_ptr 也不是針對線程安全而設(shè)計出來的呀,八竿子打不著的東西為什么會湊在一起問。 好像也就一個atmoic引用計數(shù)可以沾上邊。 首先

    2024年02月08日
    瀏覽(19)
  • 面試之快速學(xué)習(xí)C++11-完美轉(zhuǎn)發(fā),nullptr, shared_ptr,unique_ptr,weak_ptr,shared_from_this

    函數(shù)模版可以將自己的參數(shù)完美地轉(zhuǎn)發(fā)給內(nèi)部調(diào)用的其他函數(shù)。所謂完美,即不僅能準確地轉(zhuǎn)發(fā)參數(shù)的值,還能保證被轉(zhuǎn)發(fā)參數(shù)的左右值屬性不變 引用折疊:如果任一引用為左值引用,則結(jié)果為左值引用,否則為右值引用。 上述 T 為int 。 那么整個為 int - int 回到完美轉(zhuǎn)發(fā),

    2024年02月12日
    瀏覽(15)
  • 【cmu15445c++入門】(8)C++ 智能指針unique_ptr

    【cmu15445c++入門】(8)C++ 智能指針unique_ptr

    智能指針是一種數(shù)據(jù)結(jié)構(gòu),用于沒有內(nèi)置內(nèi)存管理的語言(例如 C++)中的內(nèi)存管理(有時還有其他功能)。內(nèi)置內(nèi)存管理的語言的指的是具有垃圾回收功能的語言,如Java、Python。 現(xiàn)代C++標準庫的兩個智能指針(以及您將在類中使用的智能指針)是 std::unique_ptr 和 std::shared_

    2024年02月20日
    瀏覽(14)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包