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 ...