




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第C++11智能指針的具體使用示例詳解:
利用引用計數(shù)簡單的實現(xiàn)SharedPtr,了解原理:
templateclassT
classSharedPtr
public:
SharedPtr(T*ptr)
:_ptr(ptr)
,_count(newint(1))
SharedPtr(constSharedPtrTsp)
:_ptr(sp._ptr)
,_count(sp._count)
//計數(shù)器累加
++(*_count);
SharedPtroperator=(constSharedPtrTsp)
//判斷管理的是否是同一份資源
if(_ptr!=sp._ptr)
//計數(shù)-1,判斷之前管理的資源是否需要釋放
if((--(*_count))==0)
delete_ptr;
delete_count;
_ptr=sp._ptr;
_count=sp._count;
//計數(shù)器累加
++(*_count);
return*this;
T*operator-()
return_ptr;
Toperator*()
return*_ptr;
~SharedPtr()
if(--(*_count)==0)
delete_ptr;
delete_count;
_ptr=nullptr;
_count=nullptr;
private:
T*_ptr;
int*_count;//給每份資源開辟一個計數(shù)器
但是還存在一個線程安全的問題:
智能指針對象中引用計數(shù)是多個智能指針對象共享的,兩個線程中智能指針的引用計數(shù)同時++或–,這個操作不是原子的,引用計數(shù)原來是1,++了兩次,可能還是2。這樣引用計數(shù)就錯亂了。會導致資源未釋放或者程序崩潰的問題。所以只能指針中引用計數(shù)++、--是需要加鎖的,也就是說引用計數(shù)的操作是線程安全的。
智能指針管理的對象存放在堆上,兩個線程中同時去訪問,會導致線程安全問題。
這里我們通過加鎖來解決線程安全問題:
templateclassT
classSharedPtr
public:
SharedPtr(T*ptr)
:_ptr(ptr)
,_count(newint(1))
,_mutex(newmutex)
SharedPtr(constSharedPtrTsp)
:_ptr(sp._ptr)
,_count(sp._count)
,_mutex(sp._mutex)
//計數(shù)器累加
AddCount();
SharedPtroperator=(constSharedPtrTsp)
//判斷管理的是否是同一份資源
if(_ptr!=sp._ptr)
//計數(shù)-1,判斷之前管理的資源是否需要釋放
if(SubCount()==0)
delete_ptr;
delete_count;
delete_mutex;
_ptr=sp._ptr;
_count=sp._count;
_mutex=sp._mutex;
//計數(shù)器累加
AddCount();
return*this;
//線程安全的累加器
intAddCount()
//加鎖
_mutex-lock();
++(*_count);
_mutex-unlock();
return*_count;
intSubCount()
_mutex-lock();
--(*_count);
_mutex-unlock();
return*_count;
T*operator-()
return_ptr;
Toperator*()
return*_ptr;
~SharedPtr()
if(SubCount()==0)
delete_ptr;
delete_count;
delete_mutex;
_ptr=nullptr;
_count=nullptr;
_mutex=nullptr;
private:
T*_ptr;
int*_count;//給每份資源開辟一個計數(shù)器
mutex*_mutex;//每一份資源有一個獨立的鎖
shared_ptr的循環(huán)引用
循環(huán)引用的場景:
structListNode
int_data;
shared_ptrListNode_prev;
shared_ptrListNode_next;
~ListNode(){cout"~ListNode()"endl;}
voidtest()
shared_ptrListNodenode1(newListNode);
shared_ptrListNodenode2(newListNode);
node1-_next=node2;
node2-_prev=node1;
node1和node2兩個智能指針對象指向兩個節(jié)點,兩個節(jié)點的引用計數(shù)都是1。node1-next指向node2,node2-prev指向node1,兩個節(jié)點的引用計數(shù)都變成2。程序運行完之后,析構node1和node2,node1和node2所指向的節(jié)點引用計數(shù)分別減1,但是node1-next指向下面節(jié)點,node2-prev指向上面節(jié)點,此時,兩個節(jié)點的引用計數(shù)都為1,所以兩個節(jié)點不能析構。
引用計數(shù)為0時,如果要析構node1節(jié)點,就先要去析構node1中的自定義結構,然后再析構node1。也就是說node1-next析構了,node2就釋放了;node2-prev析構了,node1就釋放了。但是_next屬于node的成員,node1釋放了,_next才會析構,而node1由_prev管理,_prev屬于node2成員,所以這就叫循環(huán)引用,誰也不會釋放。
解決方案:
在引用計數(shù)的場景下,把節(jié)點中的_prev和_next改成weak_ptr就可以了
原理就是,node1-_next=node2和node2-_prev=node1時weak_ptr的_next和_prev不會增加node1和node2的引用計數(shù)。
weak_ptr最大作用就是解決shared_ptr的循環(huán)引用
structListNode
int_data;
weak_ptrListNode_prev;
weak_ptrListNode_next;
~ListNode(){cout"~ListNode()"endl;}
voidtest()
shared_ptrListNodenode1(newListNode);
shared_ptrListNodenode2(newListNode);
node1-_next=node2;
node2-_prev=node1;
注意:
weak_ptr不能單獨使用,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)療產(chǎn)品售賣管理辦法
- 北京項目備案管理辦法
- 公司廠區(qū)門衛(wèi)管理辦法
- 村鎮(zhèn)銀行股權管理辦法
- 智慧校園午餐管理辦法
- 檢測公司合同管理辦法
- 北京服務備件管理辦法
- 安全生產(chǎn)風險隱患自查報告
- 監(jiān)理生產(chǎn)安全事故隱患排查制度
- 安全生產(chǎn)標準化要素有幾個
- GB/T 27567-2011工業(yè)用吡啶
- GB/T 14549-1993電能質(zhì)量公用電網(wǎng)諧波
- DB22-T 5040-2020建設工程見證取樣檢測標準-(高清正版)
- 子宮內(nèi)膜增生演示正式課件
- 婦幼相關公共衛(wèi)生服務督導評估表
- 《支氣管舒張試驗》課件
- 婦幼保健院高危兒童管理方案
- 自愿放棄財產(chǎn)協(xié)議范本書
- Soul app用戶體驗分析市場調(diào)研分析報告PPT模板
- [瀏陽]農(nóng)村飲水安全供水工程給水管道結構施工圖14張(大院出品)
- 高中生物校本教材
評論
0/150
提交評論