這是乙個簡單的實現shared_ptr的過程 因為是小練習的緣故 其中有些地方邏輯可能並不嚴密 希望大家指正
注意點刪除器因為shared_ptr的刪除器是執行時繫結的 所以其型別應該是乙個指標 所以我們需要乙個函式指標 指向刪除器
類的型別這是乙個典型的類指標的類 有共用乙個指標 其實使用智慧型指標儲存是最優的 但是我們就是在實現智慧型指標嘛 所以就操作普通指標就好
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
template
<
typename t>
class
shared_ptr
;template
<
typename t,
typename..
. args>
inline shared_ptr
make_shared
(args&&..
. args)
//這裡只是簡單的實現而已 其中並沒有涉及到記憶體的分配 也就使得第乙個引數有點浪費
template
<
typename t>
class
shared_ptr
//預設建構函式
shared_ptr()
:ptr_count
(nullptr),
mem_ptr
(nullptr),
del_ptr
(nullptr
)//接收乙個引數的建構函式(防止隱性轉換)
explicit
shared_ptr
(t *tmp_ptr)
try:
mem_ptr
(tmp_ptr)
,ptr_count
(new
size_t(1
)),del_ptr
(nullptr
)catch
(const std::bad_alloc &err)
//不同型別轉換
template
<
class
type
>
shared_ptr
(const shared_ptr
& ptr)
:mem_ptr
(ptr-
>
get())
,del_ptr
(ptr-
>
return_del()
),ptr_count(++
(ptr-
>
use_count()
))//拷貝建構函式
shared_ptr
(shared_ptr &tmp_ptr)
noexcept
(false
)//拷貝賦值運算子
void
operator=(
const shared_ptr& tmp_ptr)
&noexcept
(false
)//不同型別轉換
template
<
class
type
>
void
operator=(
const shared_ptr
& tmp_ptr)
&noexcept
(false
)//移動建構函式
shared_ptr
(shared_ptr && tmp_ptr)
noexcept
:mem_ptr
(tmp_ptr.mem_ptr)
,ptr_count
(tmp_ptr.ptr_count)
,del_ptr
(nullptr
)//移動賦值運算子 //強制等號左邊為左值
void
operator
=(shared_ptr && ptr)
&noexcept
//過載解引用運算子
t&operator*(
) t*
operator
->()
t*get(
) size_t use_count()
bool
unique()
void
swap
(shared_ptr &tmp_ptr)
void
reset()
else
}void
reset
(t *tmp_ptr)
else
mem_ptr = tmp_ptr;
ptr_count =
newsize_t(1
);//看起來很奇怪 仔細想想 如果count不為零的話其他智慧型指標還要使用
}//接收乙個指標和乙個自定義的刪除器 用於在析構時正確釋放物件 預設為delete
void
reset
(t *tmp_ptr,
void
(*del_ptr)
(t *))
--(*ptr_count)
; mem_ptr = tmp_ptr;
ptr_count =
newsize_t(1
);del_ptr = del_ptr;
//定義乙個刪除器}~
shared_ptr()
if((*ptr_count)==0
)--*ptr_count;if(
*ptr_count==0)
}catch(.
..)}
};//乙個測試用的聚合類
struct text
;void
del(text* tmp)
//demo
intmain()
)); cout <<
(*tmpc_ptr)
.ans <<
" "<<
(*tmpc_ptr)
.weight << endl;
tmpc_ptr.
reset
(new
text()
);cout <<
(*tmpc_ptr)
.ans <<
" "<<
(*tmpc_ptr)
.weight << endl;
tmpc_ptr.
reset
(new
text()
,del)
;//shared_ptr刪除器執行時繫結 所以使用指標儲存刪除器
cout <<
"測試get函式\n"
; text *temp_text_ptr = tmpc_ptr.
get();
//此函式小心使用 會返回智慧型指標所維護的指標域
cout << temp_text_ptr-
>ans <<
" "<< temp_text_ptr-
>weight << endl;
cout <<
"開始析構\n"
;return0;
}
這是測試**的輸出
測試make_shared:
: 5測試基本操作101
102交換操作
10 5
5 10
測試三種引數的reset函式
0 25 5
10 10
測試get函式
20 20
開始析構
special complete the destructor.
commen complete the destructor.
commen complete the destructor.
commen complete the destructor.
commen complete the destructor.
在本篇部落格中只是簡單實現了make_shared 就像我們注釋中所說的 這樣的寫法導致make_shard的第乙個引數有些多餘 但實際一定不是這樣的 我們來看看make_shared的原始碼
template.. _args>
inline shared_ptr<_tp>
make_shared
(_args&&..
. __args)
我們可以看到第乙個型別引數的存在是很有必要的 為了能夠正確的分配記憶體 我們這個模板函式也應該由我們顯式的提供型別 shared ptr的簡單實現
前面講到auto ptr有個很大的缺陷就是所有權的轉移,就是乙個物件的記憶體塊只能被乙個智慧型指標物件所擁有.但我們有些時候希望共用那個記憶體塊.於是c 11標準中有了shared ptr這樣的智慧型指標,顧名思義,有個shared表明共享嘛.所以shared ptr型別的智慧型指標可以做為stl容...
shared ptr的簡單實現
shared ptr 使用引用計數 傳入指標的建構函式 拷貝建構函式 賦值函式 析構函式 獲取引用計數 和 的過載 注意事項 建構函式是explicit的,防止smart ptr int sp p 的使用 計數需要用int ptr 是先 的,所以需要括號或者 ptr smart ptr.h temp...
實現乙個簡單的 shared ptr
智慧型指標的作用有如同指標,但會記錄有多少個 shared ptrs 共同指向乙個物件。這便是所謂的引用計數。一旦最後乙個這樣的指標被銷毀,也就是一旦某個物件的引用計數變為 0,這個物件會被自動刪除。shared ptr 的實現機制其實就是在拷貝構造時使用同乙份引用計數。同乙個 shared ptr...