shared ptr原始碼結構分析

2021-10-19 08:42:01 字數 2510 閱讀 2145

shared_ptr是智慧型指標的一種,相較於unique_ptr,引入了引用計數的概念,可以支援多個智慧型指標指向同一資源,由引用計數的增減來描述資源的共享或記憶體釋放,引用計數降為0的時候,資源所占用的記憶體空間會被釋放。

觀察其原始碼結構,可以發現shared_ptr是乙個模板派生類,_ptr_base為它的基類。

shared_ptr模板類沒有自己的資料成員,而是只提供了一些供呼叫的介面,其中包括:建構函式(有多個不同版本的建構函式,對應不同的函式引數),值得注意的是,其中有乙個construct from unique_ptr,由unique_ptr作為函式引數來構造shared_ptr,並且,該引數是個右值引用

這也不難理解,因為unique_ptr無法拷貝,保證資源的唯一性,可以通過move()函式來傳參,即下面的**,構造出p之後,p1也就失效了。

接下來是運算子過載部分,shared_ptr提供了很多運算子的過載,使其使用起來接近於普通的指標,包括了「=」、「*」、「->」、「()」、「.」這些,其中每個過載函式都有許多版本,對應不同的需求,以「=」運算子過載為例,就提供了5個不同的版本。

而對於其他運算子,則是模仿指標的使用,比如「*」運算子返回指標指向的內容,「->」運算子則返回原指標。get()介面是_ptr_base類的,具體就是返回原指標。

最後是一些介面,包括swap、reset等等,從字面意思即可理解其作用。注意到reset的實現是通過swap函式的,這其實類似容器的記憶體清空,比如清空vector,也就是將其capacity置0,就可以這麼寫,vector().swap(原容器)。

以上就是shared_ptr模板類的大體結構,可以看到這個類只是提供了一些介面,具體的資料成員(原指標以及引用計數相關的資料成員),其實都是_ptr_base類裡,下面就看看這個類具體包含了什麼。

我們主要關注其資料成員,可以看到有兩個資料成員:分別是_ptr和_rep,型別分別是element_type和_ref_count_base,根據其命名就可以得知:_ptr就是原始指標,而_rep則是控制引用計數的指標,

那麼_ref_count_base類又是什麼呢,繼續看一下:

看到_ref_count_base類是乙個抽象類,它有兩個重要的資料成員和一些純虛函式(在_ref_count類中進行實現):

_atomic_counter_t型別其實就是unsigned long型別,如下:

接下來,_ref_count_base有乙個派生類_ref_count,這是真正的引用計數器物件,有乙個資料成員_ptr,就是原始指標。在 _ref_count類裡,對 _ref_count_base抽象基類的純虛函式進行了實現

使用的時候,即會將子類指標強轉為基類指標。

shared_ptr直接用原始指標構造時,先從基類開始:

會初始化基類資料成員_ty* _ptr,然後建立_ref_count_base物件,_ref_count_base物件建立時,會分別為_uses和_weaks賦值為1,其中_uses即為shared_ptr的引用計數。

具體計數器增減情況如下:

1、涉及到shared_ptr的拷貝,其所指物件的引用計數會遞增,比如以下情況:

用乙個shared_ptr初始化另乙個shared_ptr

用乙個shared_ptr給另乙個shared_ptr賦值

將shared_ptr作為引數傳遞給乙個函式

shared_ptr作為函式的返回值

2、引用計數減少的情況

給shared_ptr賦予乙個新值

shared_ptr為區域性變數離開作用域失效,或者shared_ptr被銷毀。

STL原始碼剖析 shared ptr

目錄 一 引言 二 實現 2.1 模擬實現shared ptr 2.2 測試用例 三 潛在問題分析 你可能還需要了解模擬實現c 標準庫中的auto ptr 與auto ptr大同小異,shared ptr也是乙個類。可以實現多個指標指向同乙個物件 引用計數 發生拷貝的話都指向相同的記憶體。命名說明 ...

Cartographer原始碼篇 原始碼分析 1

在安裝編譯cartographer 1.0.0的時候,我們可以看到 主要包括cartorgarpher ros cartographer ceres sover三個部分。其中,ceres solver用於非線性優化,求解最小二乘問題 cartographer ros為ros平台的封裝,獲取感測器資料...

AbstractListView原始碼分析3

normal list that does not indicate choices public static final int choice mode none 0 the list allows up to one choice public static final int choice ...