C++標(biāo)準(zhǔn)庫學(xué)習(xí)之weak_ptr智能指針用法詳解
在上一篇文章中介紹了 shared_ptr 這種智能指針,他為了解決在指針沒有引用的情況下自動(dòng)回收資源這種情況而產(chǎn)生的,但是在部分情況下會(huì)產(chǎn)生另一種問題,那就是兩個(gè)智能指針被循環(huán)引用 , a 使用 shared_ptr 引用了b ,同時(shí) b 使用 shared_ptr 引用了 a,在 方法執(zhí)行完成后 ,a 與 b 的智能指針都會(huì)被 釋放,但是 由于他們互相持有 , a 與 b 的 used_count >0 ,那么就不會(huì)釋放他們的資源,看下面的例子
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class Person{
public:
// 構(gòu)造方法 ,name 是必要參數(shù) mum 與 dad 是非必要參數(shù)
Person(string name,shared_ptr<Person> mum = nullptr ,shared_ptr<Person> dad = nullptr)
:name(name) ,mum(mum),dad(dad)// 此種初始化方式被經(jīng)常應(yīng)用到 jni 源碼上
{
}
// 析構(gòu)函數(shù),資源被釋放時(shí)會(huì)被調(diào)用
~Person(){
cout<<"對(duì)象名稱是->" << name<< "被回收了"<<endl;
}
// 向量
vector<shared_ptr<Person>> child;
//名字
string name;
// 智能指針引用mum
shared_ptr<Person> mum;
//智能指針引用dad
shared_ptr<Person> dad;
};
// 初始化 家人,讓他們循環(huán)引用
shared_ptr<Person> getFamily(const string& name){
shared_ptr<Person> mum(new Person(name +"'s Mum"));
shared_ptr<Person> dad(new Person(name +"'s Dad"));
shared_ptr<Person> child(new Person(name,mum,dad));
mum->child.push_back(child);
dad->child.push_back(child);
return child;
}
int main(){
shared_ptr<Person> tsm= getFamily("tsm");
cout<< "------------before change-----------"<<endl;
cout << tsm->dad->name<<endl;
cout << tsm->mum->name<<endl;
cout << tsm->name<<endl;
cout<<"tsm 的引用個(gè)數(shù)" <<tsm.use_count()<<endl;
cout<< "------------start change-----------"<<endl;
tsm = getFamily("tsm1");
cout<< "------------after change-----------"<<endl;
system("pause");
return 0;
}結(jié)果:
D:\CWorkSpace\tsmTest\cmake-build-debug\tsmTest.exe
------------before change-----------
tsm's Dad
tsm's Mum
tsm
tsm 的引用個(gè)數(shù)3
------------start change-----------
------------after change-----------
. . . pause . . .
發(fā)現(xiàn)在為 tsm 這個(gè)變量二次賦值時(shí),第一次 shared_ptr 指針指向的資源內(nèi)存應(yīng)該是被釋放的,但是他們的析構(gòu)函數(shù)并沒有被執(zhí)行,那就證明他的資源并沒有被釋放,那么我們?nèi)绾蝸硇薷膬?nèi),這就引出了我們今天的主角 weak_ptr
修改如下
class Person{
public:
// 構(gòu)造方法 ,name 是必要參數(shù) mum 與 dad 是非必要參數(shù)
Person(string name,shared_ptr<Person> mum = nullptr ,shared_ptr<Person> dad = nullptr)
:name(name) ,mum(mum),dad(dad)// 此種初始化方式被經(jīng)常應(yīng)用到 jni 源碼上
{
}
// 析構(gòu)函數(shù),資源被釋放時(shí)會(huì)被調(diào)用
~Person(){
cout<<"對(duì)象名稱是->" << name<< "被回收了"<<endl;
}
// 將向量中的引用使用 weak_ptr ,打破互相引用即可
vector<weak_ptr<Person>> child;
//名字
string name;
// 智能指針引用mum
shared_ptr<Person> mum;
//智能指針引用dad
shared_ptr<Person> dad;
};修改后的結(jié)果如下:
------------before change-----------
tsm's Dad
tsm's Mum
tsm
tsm 的引用個(gè)數(shù)1
------------start change-----------
對(duì)象名稱是->tsm被回收了
對(duì)象名稱是->tsm's Dad被回收了
對(duì)象名稱是->tsm's Mum被回收了
------------after change-----------
發(fā)現(xiàn)在使用 weak_ptr 打破互相引用的后, 被覆蓋的 tsm 的析構(gòu)函數(shù)被成功調(diào)用了,
weak_ptr 的使用場(chǎng)景主要有2個(gè)
1: 打破 shared_ptr 使用混亂出現(xiàn)的情況導(dǎo)致循環(huán)引用的情況,
2: 如果持有該 shared_ptr 的對(duì)象的生命周期是大于 該 shared_ptr 指針的生命周期的情況,就會(huì)導(dǎo)致 shared_ptr 資源無法被回收,
weak_ptr 的創(chuàng)建方式有3中
1:
weak_ptr<Person> t0; //構(gòu)造空對(duì)象
2:
weak_ptr<Person> t1(t0); //使用拷貝構(gòu)造函數(shù)
3:
shared_ptr<Person> tsm= getFamily("tsm");
weak_ptr<Person> t2(tsm);
檢查weak_ptr 是否還有效
t2.expired()
expired 源碼如下
bool
expired() const noexcept
{ return _M_refcount._M_get_use_count() == 0; }
可以看到 返回的是 use_count ,那就證明 if(!t2.expired) 則證明他是有效的
使用 weak_ptr,使用lock 方法將 weak_ptr 轉(zhuǎn)換成 shared_ptr ,防止在使用過程中資源被回收
shared_ptr<Person> tt = t2.lock();
看一下lock 的源碼
shared_ptr<_Tp>
lock() const noexcept
{ return shared_ptr<_Tp>(*this, std::nothrow); }
到此這篇關(guān)于C++標(biāo)準(zhǔn)庫學(xué)習(xí)之weak_ptr智能指針用法詳解的文章就介紹到這了,更多相關(guān)C++ weak_ptr智能指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++ 學(xué)習(xí)筆記實(shí)戰(zhàn)寫一個(gè)簡(jiǎn)單的線程池示例
- C++學(xué)習(xí)之如何進(jìn)行內(nèi)存資源管理
- C++中set的用法學(xué)習(xí)
- C++學(xué)習(xí)之命名空間詳解
- C++學(xué)習(xí)之異常機(jī)制詳解
- C++ OpenCV學(xué)習(xí)之圖像金字塔與圖像融合詳解
- C++序列操作函數(shù)學(xué)習(xí)最全指南
- C++ OpenCV學(xué)習(xí)之圖像像素值統(tǒng)計(jì)
- C/C++ 多線程的學(xué)習(xí)心得總結(jié)
- C++中的while循環(huán)和for循環(huán)語句學(xué)習(xí)教程
- C++ 學(xué)習(xí)之旅 Windows程序內(nèi)部運(yùn)行原理
- C++入門之基礎(chǔ)語法學(xué)習(xí)教程
- C++ 入門指南:零基礎(chǔ)入門教學(xué)
相關(guān)文章
Visual Studio Code運(yùn)行C++代碼時(shí)顯示CLOCKS_PER_SEC未定義的問題及解決方法
這篇文章主要介紹了解決Visual Studio Code運(yùn)行C++代碼時(shí)顯示CLOCKS_PER_SEC未定義的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
C語言數(shù)據(jù)結(jié)構(gòu)與算法之時(shí)間空間復(fù)雜度入門
這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)與算法之時(shí)間空間復(fù)雜度的入門教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
C++詳解Primer文本查詢程序的實(shí)現(xiàn)
這個(gè)程序還是比較復(fù)雜的,把這句話作為文章的開頭可以看出它的真實(shí)性.....這篇文章主要介紹了文本查詢程序的實(shí)現(xiàn),下面我們一起來看看2022-06-06
基于Matlab實(shí)現(xiàn)水波倒影特效的制作
這篇文章主要介紹了如何利用Matlab制作出水波倒影的特效,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Matlab有一定幫助,需要的可以參考一下2022-03-03

