日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C++智能指針enable_shared_from_this

enable_shared_from_this介紹

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

創(chuàng)新互聯(lián)是專業(yè)的東安網(wǎng)站建設公司,東安接單;提供成都網(wǎng)站設計、網(wǎng)站制作,網(wǎng)頁設計,網(wǎng)站設計,建網(wǎng)站,PHP網(wǎng)站建設等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行東安網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!

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

我們來看看以下代碼例子,如果先不運行,你能看出什么問題嗎?

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

    };
    std::shared_ptr getPtr(){
        return std::shared_ptr(this);
    }
};

int main() {
    std::shared_ptr person = std::make_shared();
    std::shared_ptr 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;
}

以上代碼運行崩潰報錯了,這是為什么呢?

崩潰信息

這是因為只有一個Person的指針,但是卻被兩個智能指針shared_ptr持有,而它們的引用計數(shù)都是1,因此當main函數(shù)運行完畢后兩個智能指針釋放時都對同一個Person指針進行釋放導致的崩潰。

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

如下是實例代碼:

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

    };
    std::shared_ptr getPtr(){
        return shared_from_this();
    }
};

int main() {
    std::shared_ptr person = std::make_shared();
    std::shared_ptr 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;
}

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

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

更多關于enable_shared_from_this的實踐對比可以參照官網(wǎng)學習:https://en.cppreference.com/w/cpp/memory/enable_shared_from_this

enable_shared_from_this的實現(xiàn)

我們通過源碼的方式來分析下enable_shared_from_this的實現(xiàn)原理,enable_shared_from_this的源碼非常簡短:

template
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(__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 weak_from_this() const _NOEXCEPT
        { return __weak_this_; }
#endif // _LIBCPP_STD_VER > 14

    template  friend class shared_ptr;
};

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

C++之CRTP的使用

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

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

崩潰信息


分享標題:C++智能指針enable_shared_from_this
網(wǎng)頁路徑:http://m.5511xx.com/article/cospgei.html