成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++智能指針enable_shared_from_this

開(kāi)發(fā) 前端
enable_shared_from_this其實(shí)是智能指針中的內(nèi)容,它的作用就是用于在類的內(nèi)部,返回一個(gè)this的智能指針。

enable_shared_from_this介紹

enable_shared_from_this其實(shí)是智能指針中的內(nèi)容,它的作用就是用于在類的內(nèi)部,返回一個(gè)this的智能指針。

對(duì)于enable_shared_from_this,初學(xué)者可能不明白它的使用場(chǎng)景和使用的必要性,可能有得童鞋們會(huì)問(wèn)既然有了this這個(gè)指向自己的指針, 為什么還需要enable_shared_from_this這個(gè)東西呢,直接用this代替不就好了嗎?

我們來(lái)看看以下代碼例子,如果先不運(yùn)行,你能看出什么問(wèn)題嗎?

#include <iostream>
class Person{
public:
    Person() = default;
    ~Person(){

    };
    std::shared_ptr<Person> getPtr(){
        return std::shared_ptr<Person>(this);
    }
};

int main() {
    std::shared_ptr<Person> person = std::make_shared<Person>();
    std::shared_ptr<Person> person1 = person->getPtr();
    std::cout << "person.use_count() = " << person.use_count() << std::endl;
    std::cout << "person1.use_count() = " << person1.use_count() << std::endl;
    return 0;
}

以上代碼運(yùn)行崩潰報(bào)錯(cuò)了,這是為什么呢?

崩潰信息

這是因?yàn)橹挥幸粋€(gè)Person的指針,但是卻被兩個(gè)智能指針shared_ptr持有,而它們的引用計(jì)數(shù)都是1,因此當(dāng)main函數(shù)運(yùn)行完畢后兩個(gè)智能指針釋放時(shí)都對(duì)同一個(gè)Person指針進(jìn)行釋放導(dǎo)致的崩潰。

如果我們能讓兩個(gè)智能指針shared_ptr共享同一個(gè)引用計(jì)數(shù),那么這個(gè)崩潰問(wèn)題就迎刃而解了。而通過(guò)讓Person繼承基類enable_shared_from_this,然后在函數(shù)getPtr中 調(diào)用基類的shared_from_this就能返回一個(gè)this的智能指針,這樣即可實(shí)現(xiàn)讓多個(gè)智能指針共享同一個(gè)引用計(jì)數(shù),而達(dá)到銷(xiāo)毀時(shí)只釋放一次的目的。這就是enable_shared_from_this存在的必要性, 這也是this無(wú)法替代的功能點(diǎn)。

如下是實(shí)例代碼:

#include <iostream>
class Person:public std::enable_shared_from_this<Person>{
public:
    Person() = default;
    ~Person(){

    };
    std::shared_ptr<Person> getPtr(){
        return shared_from_this();
    }
};

int main() {
    std::shared_ptr<Person> person = std::make_shared<Person>();
    std::shared_ptr<Person> person1 = person->getPtr();
    std::cout << "person.use_count() = " << person.use_count() << std::endl;
    std::cout << "person1.use_count() = " << person1.use_count() << std::endl;
    return 0;
}

通過(guò)運(yùn)行調(diào)試打印,我們可以看到這person和person1這兩個(gè)智能指針的引用計(jì)數(shù)都變?yōu)榱?,這是正確的。

通過(guò)兩個(gè)實(shí)例代碼的對(duì)比,我們可以發(fā)現(xiàn)問(wèn)題的根源所在就是我們?cè)诜祷豻his的智能指針時(shí),直接調(diào)用std::shared_ptr構(gòu)造函數(shù)傳入裸指針的方式構(gòu)造一個(gè)智能指針, 而在之前的介紹中我們提到過(guò)使用智能指針shared_ptr時(shí)盡量使用std::make_shared進(jìn)行智能指針的構(gòu)造,避免直接調(diào)用std::shared_ptr構(gòu)造函數(shù)傳入裸指針的方式進(jìn)行構(gòu)造。

更多關(guān)于enable_shared_from_this的實(shí)踐對(duì)比可以參照官網(wǎng)學(xué)習(xí):https://en.cppreference.com/w/cpp/memory/enable_shared_from_this

enable_shared_from_this的實(shí)現(xiàn)

我們通過(guò)源碼的方式來(lái)分析下enable_shared_from_this的實(shí)現(xiàn)原理,enable_shared_from_this的源碼非常簡(jiǎn)短:

template<class _Tp>
class _LIBCPP_TEMPLATE_VIS enable_shared_from_this
{
    mutable weak_ptr<_Tp> __weak_this_;
protected:
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    enable_shared_from_this() _NOEXCEPT {}
    _LIBCPP_INLINE_VISIBILITY
    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
    _LIBCPP_INLINE_VISIBILITY
    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
        {return *this;}
    _LIBCPP_INLINE_VISIBILITY
    ~enable_shared_from_this() {}
public:
    _LIBCPP_INLINE_VISIBILITY
    shared_ptr<_Tp> shared_from_this()
        {return shared_ptr<_Tp>(__weak_this_);}
    _LIBCPP_INLINE_VISIBILITY
    shared_ptr<_Tp const> shared_from_this() const
        {return shared_ptr<const _Tp>(__weak_this_);}

#if _LIBCPP_STD_VER > 14
    _LIBCPP_INLINE_VISIBILITY
    weak_ptr<_Tp> weak_from_this() _NOEXCEPT
       { return __weak_this_; }

    _LIBCPP_INLINE_VISIBILITY
    weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
        { return __weak_this_; }
#endif // _LIBCPP_STD_VER > 14

    template <class _Up> friend class shared_ptr;
};

通過(guò)源碼我們可以發(fā)現(xiàn)這是一個(gè)模版類,將自身類型以模版參數(shù)的形式傳入到父類,這是典型的CRTP應(yīng)用,關(guān)于CRTP之前我們已經(jīng)介紹過(guò)了,這里不再累贅。感興趣的童鞋們可以參考之前的博文:

C++之CRTP的使用

enable_shared_from_this對(duì)外只提供了一個(gè)weak_from_this公共方法,其內(nèi)部通過(guò)以為弱引用的智能指針weak_ptr構(gòu)造了一個(gè)shared_ptr,這里并沒(méi)有什么問(wèn)題, 問(wèn)題這個(gè)弱引用的智能指針__weak_this_它是在哪里初始化的呢?我們通shared_ptr的構(gòu)造函數(shù)可以發(fā)現(xiàn),如果傳入的weak_ptr沒(méi)有初始化的話是會(huì)拋出異常崩潰的。

其實(shí)成員變量__weak_this_的初始化是在類的外部進(jìn)行初始化的,它的奧秘就是源碼的倒數(shù)第二行template ();改為不使用智能指針, 而使用裸指針的方式,修改為 auto person = new Person;,同時(shí)注釋掉第16行再運(yùn)行是會(huì)崩潰的,這就是因?yàn)開(kāi)_weak_this_沒(méi)有進(jìn)行初始化的原因。

崩潰信息

責(zé)任編輯:趙寧寧 來(lái)源: 思想覺(jué)悟
相關(guān)推薦

2010-02-05 14:36:20

C++智能指針

2010-12-17 10:07:59

2021-09-09 17:05:36

C++智能指針語(yǔ)言

2024-12-26 10:45:08

2023-12-20 12:40:51

C++RAII編程

2025-02-26 01:23:02

C++11Raw代碼

2024-01-24 11:44:44

C++智能指針開(kāi)發(fā)

2015-07-27 11:34:03

Linux內(nèi)核指針

2024-03-01 16:43:48

C++11智能指針內(nèi)存

2021-08-11 09:01:48

智能指針Box

2010-01-27 14:18:41

Android智能指針

2021-12-21 15:31:10

C++語(yǔ)言指針

2021-07-29 06:09:05

萬(wàn)能指針C語(yǔ)言void

2011-07-01 14:28:47

Qt 指針

2010-01-26 13:42:28

C++指針

2011-04-11 11:09:50

this指針

2021-07-30 05:12:54

智能指針C++編程語(yǔ)言

2014-01-24 09:49:01

C++指針

2021-10-27 16:27:20

C++指針操控

2010-01-28 13:57:19

C++指針基礎(chǔ)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美一级免费观看 | 久久精品网 | 草久在线视频 | 国产福利在线小视频 | 亚洲精品电影在线观看 | 在线色网 | av电影一区| 亚洲精品丝袜日韩 | 狠狠做深爱婷婷综合一区 | 一区二区视频在线 | 亚洲视频www | 国产男女猛烈无遮掩视频免费网站 | 国产成人精品一区二区三区网站观看 | 最近日韩中文字幕 | 日韩一区二区三区在线视频 | 91在线精品视频 | 久草色视频 | 欧美在线 | 国产精品福利在线 | 成人在线视频免费播放 | 超碰520 | 欧美一区2区三区4区公司二百 | 中文字幕在线精品 | 亚洲一区二区三区桃乃木香奈 | 亚洲视频一区在线观看 | 国产精品不卡 | 黄色网址大全在线观看 | 99久久精品国产一区二区三区 | 亚洲精选一区二区 | 国产精品一区二区三区四区 | 亚洲va国产日韩欧美精品色婷婷 | 欧美激情一区二区三区 | 中文字幕人成乱码在线观看 | 国产草草视频 | 日韩不卡一区二区 | 日韩aⅴ片| 久久久精品综合 | 久久精品日产第一区二区三区 | 精品自拍视频 | 午夜影院 | 久在线 |