????首先看cppreference的解釋:
std::enable_shared_from_this?allows an object?t?that is currently managed by a?std::shared_ptr?named?pt?to safely generate additional?std::shared_ptr?instances?pt1, pt2, ...?that all share ownership of?t?with?pt.Publicly inheriting from?std::enable_shared_from_this?provides the type?T?with a member function?shared_from_this. If an object?t?of type?T?is managed by a?std::shared_ptr?named?pt, then calling?T::shared_from_this?will return a new?std::shared_ptr?that shares ownership of?t?with?pt
意思就是說廉涕,如果一個T類型的對象t,是被std::shared_ptr管理的艇拍,且類型T繼承自std::enable_shared_from_this狐蜕,那么T就有個shared_from_this的成員函數(shù),這個函數(shù)返回一個新的std::shared_ptr的對象卸夕,也指向?qū)ο髏层释。
? ? 那么這個特性的應(yīng)用場景是什么呢?一個主要的場景是保證異步回調(diào)函數(shù)中操作的對象仍然有效娇哆。比如有這樣一個類:
Foo::Bar接受一個函數(shù)對象湃累,這個對象需要一個Foo*指針,其實要的就是Foo::Bar的this指針碍讨,但是這個回調(diào)是異步的治力,也就是說可能在調(diào)用這個回調(diào)函數(shù)時,this指向的Foo對象已經(jīng)提前析構(gòu)了勃黍。這時候宵统,std::enable_shared_from_this就派上用場了。修改后如下:
這樣就可以保證異步回調(diào)時覆获,F(xiàn)oo對象仍然有效马澈。
? ? 注意到cppreference中說道,必須要是std::shared_ptr管理的對象弄息,調(diào)用shared_from_this才是有效的痊班,為什么呢?這個就需要看看std::enable_shared_from_this的實現(xiàn)原理了:
? ? std::enable_shared_from_this<T> 有一個std::weak_ptr<T>的成員摹量,實際上在構(gòu)造std::enable_shared_from_this<T>時涤伐,并沒有初始化std::weak_ptr<T>成員,而是在用這個std::enable_shared_from_this<T>去構(gòu)造std::shared_ptr的時候缨称,去構(gòu)造并初始化這個std::weak_ptr<T>成員凝果。所以這也就是為什么cppreference中說的這個對象必須是std::shared_ptr管理的,因為這個對象不是通過std::shared_ptr來管理睦尽,那么std::weak_ptr是未初始化的器净,無法通過其提升為std::shared_ptr對象。OK当凡,原理說了山害,具體實現(xiàn)可以去看代碼纠俭,不了解std::weak_ptr和std::shared_ptr的關(guān)系的,可以看看這篇文章:關(guān)于shared_ptr的幾個問題