智慧型指標原始碼分析 2 shared ptr

2021-10-02 18:20:33 字數 3914 閱讀 9500

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 世界裡,也不是無緣無故的出現智慧型指標。搞清楚智慧型指標的設計動機,對於正確的理解智慧型指標工作原理 設計思想 以及適用場合是有著非常直接的幫助。所以,讓我...