C++ 智能指针五
/*
代碼分析:這是標準庫的源碼,我們看到在enable_shared_from_this內部保存了一個weak_ptr。shared_from_this函數就是通過這個weak_ptr得到了。
但是另外一點,我們可以看到在enable_shared_from_this的構造函數中并沒有對這個weak_ptr進行初始化。
這就是為什么我們不能在構造函數調用shared_from_this()的原因,因為其內部的weak_ptr并沒有初始化。所以會產生錯誤。在實際的編程中如果我們需要在對象初始化中用到自己的shared_ptr。可
以單獨將初始化操作放到一個獨立的init函數中,這時候再調用shared_from_this()是沒有問題的(但還是有點問題,下面會講到)熟悉weak_ptr的同學可能知道,我們在使用weak_ptr前,需要用一個shared_ptr來對其進行初始化。
對weak_ptr初始化是要能獲取到當前對象的引用計數對象,而引用計數對象可以通過shared_ptr對象獲取到。
當然我們同樣可以用一個已經初始化過的weak_ptr來初始化另一個weak_ptr,因為已初始化的weak_ptr也可能獲取到對象的引用計數。enable_shared_from_this內部的weak_ptr是通過_Do_enable函數初始化的。
而_Do_enable函數實在shared_ptr的構造函數中調用的,這是至關重要的一個環節。
正因為如此我們在調用shared_from_this之前請確保程序已經顯式地創建了shared_ptr對象,
要不然enable_shared_from_this內部的weak_ptr始終是無效。同理在析構函數中也不能調用shared_from_this()。
在析構時,引用計數已經變為零,weak_ptr已經相當于指向的是一個無效的對象,這是不能通過此無效的weak_ptr構造shared_ptr。*/template<class _Ty>
class enable_shared_from_this
{ // provide member functions that create shared_ptr to this
public:typedef _Ty _EStype;shared_ptr<_Ty> shared_from_this(){ // return shared_ptrreturn (shared_ptr<_Ty>(_Wptr));}shared_ptr<const _Ty> shared_from_this() const{ // return shared_ptrreturn (shared_ptr<const _Ty>(_Wptr));}protected:enable_shared_from_this(){ // construct (do nothing)
}enable_shared_from_this(const enable_shared_from_this&){ // construct (do nothing)
}enable_shared_from_this& operator=(const enable_shared_from_this&){ // assign (do nothing)return (*this);}~enable_shared_from_this(){ // destroy (do nothing)
}private://友元函數template<class _Ty1,class _Ty2>friend void _Do_enable(_Ty1 *, enable_shared_from_this<_Ty2>*, _Ref_count_base *);mutable weak_ptr<_Ty> _Wptr;
};template<class _Ty1,class _Ty2>
inline void _Do_enable(_Ty1 *_Ptr, enable_shared_from_this<_Ty2> *_Es, _Ref_count_base *_Refptr)
{ // reset internal weak pointer_Es->_Wptr._Resetw(_Ptr, _Refptr);
} /* 智能指針shared_from_this崩潰問題分析 */#include <iostream>
#include <memory>class TestClass : public std::enable_shared_from_this<TestClass>
{
public:TestClass(){}~TestClass(){}void show(){printf("hello world .\n");}std::shared_ptr<TestClass> getPtr(){return shared_from_this();}
};int main()
{TestClass t;t.getPtr(); //shared_from_this()錯誤
TestClass* t1(new TestClass());t1->getPtr();//shared_from_this()錯誤
std::shared_ptr<TestClass> t2(new TestClass());t2->getPtr(); //正確,已提前創建了shared_ptr
}
?
轉載于:https://www.cnblogs.com/zhanggaofeng/p/10294507.html
總結
- 上一篇: tcl电视直播下载?
- 下一篇: C++ 贪吃蛇小游戏