解析c++ 中智能指針引用計(jì)數(shù)為什么不是0原理
問題示例1:
#include<memory> #include<cstdio> #include<map> using namespace std; int main() { shared_ptr<int> ptr = make_shared<int>(100); printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count()); map<int, shared_ptr<int>> mp; mp.insert(pair<int, shared_ptr<int>>(1, ptr)); mp.insert(pair<int, shared_ptr<int>>(2, ptr)); printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count()); mp.clear(); mp.clear(); printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count()); return 0; }
輸出:
=100,count=1
=100,count=3
=100,count=1 // 為什么這里引用計(jì)數(shù)是1而不是0呢?
問題示例2:
#include<memory> #include<cstdio> #include<map> using namespace std; int main() { shared_ptr<int> ptr = make_shared<int>(100); printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count()); map<int, shared_ptr<int>> mp; mp.insert(pair<int, shared_ptr<int>>(1, ptr)); mp.insert(pair<int, shared_ptr<int>>(2, ptr)); printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count()); ptr.reset(); printf("count=%ld\n", ptr.use_count()); return 0; }
輸出:
=100,count=1
=100,count=3
count=0 //這里為什么是0而不是2呢? 一直理解的 reset()是引用計(jì)數(shù)減1.
解析
問題1:
ptr 還在,還有一個(gè)引用。
問題2:
reset 之后,ptr 的指向改變,引用計(jì)數(shù)已經(jīng)不是原來指針的引用計(jì)數(shù)了。新指針是個(gè) nullptr ,引用計(jì)數(shù)為 0 。原來的指針引用計(jì)數(shù)是 2 ,兩個(gè)引用都在 map 里,已經(jīng)無法通過 ptr 訪問。
- 對(duì)于問題 1 中的第三次輸出,ptr 沒有釋放,因此還有 1 個(gè)引用計(jì)數(shù)占用,打印 1.
- 對(duì)于問題 2 中的第三次輸出,是 ptr 這個(gè)共享指針本身釋放,而非資源釋放,因此 ptr.use_count() 打印 0.
可以運(yùn)行下面代碼驗(yàn)證:
#include<memory> #include<cstdio> #include<map> using namespace std; int main() { shared_ptr<int> ptr = make_shared<int>(100); printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count()); map<int, shared_ptr<int>> mp; mp.insert(pair<int, shared_ptr<int>>(1, ptr)); mp.insert(pair<int, shared_ptr<int>>(2, ptr)); printf("=%d,count=%ld\n", *ptr.get(), ptr.use_count()); ptr.reset(); printf("count=%ld\n", ptr.use_count()); printf("=%d,count=%ld\n", *mp[1].get(), mp[1].use_count()); printf("=%d,count=%ld\n", *mp[2].get(), mp[2].use_count()); return 0; }
輸出:
=100,count=1
=100,count=3
count=0
=100,count=2
=100,count=2
函數(shù)邏輯
你可以設(shè)想一下這個(gè)函數(shù)的邏輯
void reset() _NOEXCEPT { shared_ptr().swap(*this); }
第一步, 創(chuàng)造一個(gè)空shared_ptr對(duì)象,與原智能指針交換.交換后指向nullptr,引用為0;
第二步, 原始的指針成了右值, 在語句調(diào)用結(jié)束消滅, 隨即, 原資源引用數(shù)減一, 如減為0, 自行消滅,否則繼續(xù)留存.
以上就是解析C語言中智能指針引用計(jì)數(shù)為什么不是0原理的詳細(xì)內(nèi)容,更多關(guān)于C語言智能指針引用計(jì)數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++實(shí)現(xiàn)學(xué)生選課系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)學(xué)生選課系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02用c語言實(shí)現(xiàn)一個(gè)電話薄(附完整代碼)
大家好,本篇文章主要講的是用c語言實(shí)現(xiàn)一個(gè)電話薄(附完整代碼),感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01C++用read()和write()讀寫二進(jìn)制文件的超詳細(xì)教程
二進(jìn)制的文件肉眼我們是讀不懂的,如果通過二進(jìn)制的讀寫操作就可以讀懂,下面這篇文章主要給大家介紹了關(guān)于C++用read()和write()讀寫二進(jìn)制文件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06C/C++通過HTTP實(shí)現(xiàn)文件上傳與下載的示例詳解
WinInet是 Microsoft Windows 操作系統(tǒng)中的一個(gè) API 集,用于提供對(duì) Internet 相關(guān)功能的支持,它包括了一系列的函數(shù),使得 Windows 應(yīng)用程序能夠進(jìn)行網(wǎng)絡(luò)通信、處理 HTTP 請(qǐng)求、FTP 操作等,本文給大家介紹了C/C++通過HTTP實(shí)現(xiàn)文件上傳與下載,需要的朋友可以參考下2023-12-12C++使用cjson操作Json格式文件(創(chuàng)建、插入、解析、修改、刪除)
本文主要介紹了C++使用cjson操作Json格式文件(創(chuàng)建、插入、解析、修改、刪除),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02OpenCV實(shí)現(xiàn)繞圖片中任意角度旋轉(zhuǎn)任意角度
這篇文章主要為大家詳細(xì)介紹了在圖片不被裁剪時(shí),opencv如何實(shí)現(xiàn)繞圖片中任意點(diǎn)旋轉(zhuǎn)任意角度,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-09-09數(shù)據(jù)結(jié)構(gòu)與算法:單向鏈表實(shí)現(xiàn)與封裝
今天小編就為大家分享一篇關(guān)于數(shù)據(jù)結(jié)構(gòu)與算法:單向鏈表實(shí)現(xiàn)與封裝,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12