1.簡介
毫無疑問shared_ptr才是最受歡迎的智慧型指標也是像普通指標的智慧型指標。常常聽說其內部實現是基於引用計數的那麼什麼是引用計數,其在內部又是怎樣實現的今天就讓咋來見識一下它的原始碼,在此之前,先貼乙個來自**的shared_ptr的例子熟悉一下他的具體用法:
#include
#include
#include
using
namespace boost;
using
namespace std;
int main (
)
輸出:
foo unique?
1: false
2: false
3: true
需要特別注意的是shared_ptr由於支援拷貝操作,故可以將他安全的放在標準容器裡面了
2.原始碼分析
template
<
class
t>
class
shared_ptr
;// shared_ptr
碼量過於巨大,先來康一康私有成員,畢竟成員函式都是圍繞著他們轉的呀!重點關注引用計數的資料成員shared_count pn
,其私有成員定義如下:
class
shared_count
繼續向下走關注shared_count的私有成員變數sp_counted_base:
class
sp_counted_base
//該類唯一建構函式..
.
至此已大致清楚了點,若要使用shared_ptr管理資源,根據c++在類中呼叫建構函式的順序可知先呼叫sp_counted_base的建構函式它將成員變數use_count_初始化為1,但是它什麼時候呼叫哩,shared_count的建構函式有多個首先應該呼叫哪乙個哩?以最平常的shared_ptr的建構函式來看:
template
<
class
y>
explicit
shared_ptr
( y * p ):px
( p ),pn
()// y must be complete
template
<
classt,
class
y>
inline
void
sp_pointer_construct
( boost::shared_ptr< t >
* ppx, y * p, boost::detail::shared_count & pn )
顯然在這個建構函式裡面sp_pointer_construct會呼叫shared_count的建構函式以new出來的指標為引數建立乙個臨時的shared_count物件,在如下shared_count的建構函式裡面會呼叫sp_counted_impl_p類的建構函式new出來乙個sp_counted_impl_p物件用於初始化pi_成員:
template
<
class
y>
explicit
shared_count
( y * p )
:pi_(0
)
瞅一瞅sp_counted_impl_p的建構函式:
template
<
class
x>
class
sp_counted_impl_p
:public sp_counted_base..
.
追蹤**發現sp_counted_impl_p是sp_counted_base的公有派生類,它的自定義私有成員如上,其建構函式僅僅就是用上面的p初始化這個px_,需要注意的是它也會呼叫基類的建構函式,即剛開始說的sp_counted_base的建構函式初始化use_count_為1。至此這個臨時的shared_count以及構造出來了,下一步sp_pointer_construct函式會呼叫這個臨時物件的swap函式,這樣就意味著shared_ptr裡面的shared_count成員至此完成了自身的構造啦。
3.實現自己的shared_ptr
總結起來就是說先呼叫shared_ptr物件的建構函式,然後會呼叫成員變數pn的建構函式初始化它,不過在具體實現的時候略有技巧,下面就仿照上面的流程自己構造乙個shared_ptr的基本框架:
#include
#include
#include
using
namespace std;
class
sp_counted_base
//該類唯一建構函式
virtual
~sp_counted_base()
virtual
void
dispose()
=0;void
release()
}long
use_count()
const
// nothrow
void
add_ref_copy()
};template
<
class
x>
class
sp_counted_impl_p
:public sp_counted_base
virtual
~sp_counted_impl_p()
void
dispose()
};template
<
class
t>
class
shared_count
~shared_count()
//cout<<"shared_count destroy ..."<}
shared_count
(shared_count const
& r)
:pi_
(r.pi_)
}long
use_count()
void
swap
(shared_count & r)};
template
<
class
t>
class
shared_ptr
~shared_ptr()
shared_ptr
(shared_ptr const
&r):
px(r.px),pn
(r.pn)
long
use_count()
void
swap
( shared_ptr & other )
t &operator*(
)const
shared_ptr
&operator
=(shared_ptr
const
& r)
return
*this;}
};// shared_ptr
int main (
)
輸出:
foo and bar
foo_str: hello world!; bar_str: i'm hero!
foo_use_count: 1; bar_use_count: 1
foo_str: i'm hero!; bar_str: hello world!
foo_str: hello world!; bar_str: hello world!
foo_use_count: 2; bar_use_count: 2
智慧型指標scoped ptr原始碼剖析
智慧型指標scoped ptr原始碼剖析 以下為簡化後的原始碼實現 include include include include using namespace std scoped ptr 指向乙個物件,死活不肯交出資源佔有權 私有的複製建構函式和賦值運算子 除非你和我一樣 swap scope...
智慧型指標分析
在我們寫 時,經常會忘記釋放掉動態開闢出來的記憶體,或者在我們的程式中,new和delete中間有如 throw goto return break 這樣引起執行流改變的語句時,就會造成沒有釋放資源,造成記憶體洩漏。void test1 t operator 注意函式返回值型別 上面說了智慧型指標是...
2 智慧型指標
為什麼需要智慧型指標?乙個類庫的產生勢必有其被觸發的動機,正如某句經典語所云 在這個世界上,沒有無緣無故的愛,也沒有無緣無故的恨。同樣的,在c 世界裡,也不是無緣無故的出現智慧型指標。搞清楚智慧型指標的設計動機,對於正確的理解智慧型指標工作原理 設計思想 以及適用場合是有著非常直接的幫助。所以,讓我...