在開始本文內容以前,咱們再來總結一下,前文內容:函數
1.智能指針採用RAII機制,在構造對象時進行資源的初始化,析構對象時進行資源的清理及汕尾.this
2.auto_ptr防止拷貝後析構釋放同一塊內存,採用"轉移全部權"的方法.(實際開發中auto_ptr並不實用)spa
3.scoped_ptr與auto_ptr相似,可是它與auto_ptr最大的區別是:它不能轉移全部權,即就是禁止拷貝/賦值!(固然,咱們也探討了C++中禁止拷貝對象的技術,在此不贅述)指針
回顧完前文內容後,咱們今天來討論shared_ptr.code
咱們雖然有了scoped_ptr,但在實際開發過程當中,咱們的確要是想對智能指針進行拷貝,那scoped_ptr就鞭長莫及了.對象
那麼,咱們回到原始的問題:對智能指針進行拷貝,會出現什麼狀況?內存
咱們在第二篇文章也分析了:若是對智能指針不進行特殊處理,在析構時,會將同一塊內存釋放屢次,程序會崩潰!ci
所以,咱們要想對智能指針進行拷貝,就必須作一些特殊的處理,使得析構函數只釋放一次內存.資源
此時,若是探究過深淺拷貝的同窗,可能心中已經有了答案:用引用計數!!!(深淺拷貝問題,之後我會討論,不是本文重點)開發
考慮到有些童鞋可能不知道什麼是引用計數,那我就在這裏解釋一下:
在引用計數中,每個對象負責維護對象全部引用的計數值。當一個新的引用指向對象時,引用計數器就遞增,當去掉一個引用時,引用計數就遞減。當引用計數到零時,該對象就將釋放佔有的資源。——百度百科
通俗一點的講:在本例中咱們經過count變量來記錄當前有多少個對象共同維護着這個指針,每次拷貝/賦值的時候,讓count++.
1 2 3 4 5 6 7 8 |
|
當對象析構時,首先咱們看count是否是1,若是不是1,說明還有其餘對象在維護這個指針,咱們讓count--.不然的話,就說明,只有當前對象在維護這個指針,此時就能夠愉快的把指針delete掉了.
1 2 3 4 5 6 7 8 9 10 |
|
經過這樣的的形式,就能夠保證:在多個shared_ptr對象共同維護一塊內存中,對內存只delete一次.
最終,貼上我簡化後shared_ptr的代碼.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|