欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++標(biāo)準(zhǔn)庫學(xué)習(xí)之weak_ptr智能指針用法詳解

 更新時間:2023年12月06日 14:22:53   作者:tsm  
這篇文章主要為大家詳細(xì)介紹了C++標(biāo)準(zhǔn)庫中weak_ptr智能指針用法的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

在上一篇文章中介紹了 shared_ptr 這種智能指針,他為了解決在指針沒有引用的情況下自動回收資源這種情況而產(chǎn)生的,但是在部分情況下會產(chǎn)生另一種問題,那就是兩個智能指針被循環(huán)引用 , a 使用 shared_ptr 引用了b ,同時 b 使用 shared_ptr 引用了 a,在 方法執(zhí)行完成后 ,a 與 b 的智能指針都會被 釋放,但是 由于他們互相持有 , a 與 b 的 used_count >0 ,那么就不會釋放他們的資源,看下面的例子

#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ù),資源被釋放時會被調(diào)用
    ~Person(){
        cout<<"對象名稱是->" << 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 的引用個數(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 的引用個數(shù)3
------------start change-----------
------------after change-----------
. . . pause . . . 

發(fā)現(xiàn)在為 tsm 這個變量二次賦值時,第一次 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ù),資源被釋放時會被調(diào)用
    ~Person(){
        cout<<"對象名稱是->" << 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 的引用個數(shù)1
------------start change-----------
對象名稱是->tsm被回收了
對象名稱是->tsm's Dad被回收了
對象名稱是->tsm's Mum被回收了
------------after change-----------

發(fā)現(xiàn)在使用 weak_ptr 打破互相引用的后, 被覆蓋的 tsm 的析構(gòu)函數(shù)被成功調(diào)用了,

weak_ptr 的使用場景主要有2個

1: 打破 shared_ptr 使用混亂出現(xiàn)的情況導(dǎo)致循環(huán)引用的情況,

2: 如果持有該 shared_ptr 的對象的生命周期是大于 該 shared_ptr 指針的生命周期的情況,就會導(dǎo)致 shared_ptr 資源無法被回收,

weak_ptr 的創(chuàng)建方式有3中

1:

weak_ptr<Person> t0; //構(gòu)造空對象

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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言中各種運(yùn)算類型全面總結(jié)

    C語言中各種運(yùn)算類型全面總結(jié)

    C語言運(yùn)算符是說明特定操作的符號,它是構(gòu)造C語言表達(dá)式的工具,C語言的運(yùn)算異常豐富,除了控制語句和輸入輸出以外的幾乎所有的基本操作都為運(yùn)算符處理
    2022-04-04
  • 排列和組合算法的實(shí)現(xiàn)方法_C語言經(jīng)典案例

    排列和組合算法的實(shí)現(xiàn)方法_C語言經(jīng)典案例

    下面小編就為大家?guī)硪黄帕泻徒M合算法的實(shí)現(xiàn)方法_C語言經(jīng)典案例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • C語言手把手教你實(shí)現(xiàn)貪吃蛇AI(上)

    C語言手把手教你實(shí)現(xiàn)貪吃蛇AI(上)

    這篇文章主要介紹了C語言手把手教你實(shí)現(xiàn)貪吃蛇AI,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • c++線程池實(shí)現(xiàn)方法

    c++線程池實(shí)現(xiàn)方法

    這篇文章主要介紹了c++線程池實(shí)現(xiàn)方法,實(shí)例分析了C++線程池的原理與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-06-06
  • c語言之如何求e的近似值

    c語言之如何求e的近似值

    這篇文章主要介紹了c語言之如何求e的近似值問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • C語言字符串另類用法的實(shí)現(xiàn)

    C語言字符串另類用法的實(shí)現(xiàn)

    今天小編就為大家分享一篇關(guān)于C語言字符串另類用法的實(shí)現(xiàn),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C++?引用與內(nèi)聯(lián)函數(shù)詳情

    C++?引用與內(nèi)聯(lián)函數(shù)詳情

    這篇文章主要介紹了C++?引用與內(nèi)聯(lián)函數(shù)詳情,主要分享一下關(guān)于引用的知識點(diǎn),這里都是一些比較基礎(chǔ)的知識,適合初學(xué)者,下文續(xù)航徐介紹需要的小伙伴可以參考一下
    2022-05-05
  • C++實(shí)現(xiàn)LeetCode(67.二進(jìn)制數(shù)相加)

    C++實(shí)現(xiàn)LeetCode(67.二進(jìn)制數(shù)相加)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(67.二進(jìn)制數(shù)相加),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語言指針變量作為函數(shù)參數(shù)的實(shí)現(xiàn)步驟詳解

    C語言指針變量作為函數(shù)參數(shù)的實(shí)現(xiàn)步驟詳解

    這篇文章主要介紹了C語言指針變量作為函數(shù)參數(shù)的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • 錯誤:sem_union的存儲大小未知問題的解決方法

    錯誤:sem_union的存儲大小未知問題的解決方法

    這篇文章主要介紹了錯誤:sem_union的存儲大小未知問題的解決方法,需要的朋友可以參考下
    2016-10-10

最新評論