c++enable_shared_from_this源代碼分析(from visutal studio 2017)

  • enable_shared_from_this能讓一個對象t(該對象被shared_ptr管理,假設名爲pt)安全地生成其他額外的shared_ptr實例,它們pt共享對象t的所有權。
  • 如果一個類T繼承enable_shared_from_this<T>,則會爲該類提供成員函數:shared_from_this。只允許在被std::shared_ptr管理的對象上調用shared_from_this。否則調用會導致未定義行爲(c++17前)or拋出std::bad_weak_ptr異常。
  • 關於enable_shared_from_this類的必要性和用法這裏不再贅述。我們看在vs2017中它是如何實現的。

72.png

  • enable_shared_from_this是一個模板類,模板參數是你想要通過shared_from_this提供其他shared_ptr對象的類型。在這份實現中有一個成員類型_Esft_type,這個類型的用處在後面會說到。

73.png

  • 有一個成員變量,該變量類型爲weak_ptr<_Ty>。

74.png

  • 我們使用的函數shared_from_this(),就是用這個成員變量構造對應的shared_ptr<_Ty>對象並返回的。

75.png

  • 這是shared_ptr接受一個weak_ptr作爲參數的構造函數,如果構造失敗,會拋出bad_weak_ptr異常(since c++17)。

76.png

  • 不過我們看到,在enable_shared_from_this的所有構造函數中,都沒有對_Wptr進行賦值操作,那麼這個成員變量是在哪裏被賦值的呢?說到這裏不知道大家還記不記得,我們在分析shared_ptr的源代碼的時候,出現過這麼一個函數:_Set_ptr_rep_and_enable_shared。
  • 其實看名字就可以看出來,這個函數做了兩個操作:
    1.設置ptr和rep。
    2.enable_shared。我們來看下這個函數的內部實現:

77.png

78.png

  • 其中_Can_enable_shared<_Yty>根據_Yty類型是否具有_Esft_type成員類型而選擇了不同的重載函數:

79.png

80.png

  • 如果不具有_Esft_type類型,則什麼都不做,否則爲_Ptr->_Wptr賦值。現在我們找到了enable_shared_from_this的成員變量_Wptr是在哪裏被賦值了。只有繼承了enable_shared_from_this類型的指針,其類型纔會有_Esft_type成員類型,換句話說,這個成員類型就是用來區分shared_ptr的模板參數類型是否繼承了enable_shared_from_this<T>這個類。
  • 總結:enable_shared_from_this的一種實現方法是,其內部有一個weak_ptr類型的成員變量_Wptr,當shared_ptr構造的時候,如果其模板類型繼承了enable_shared_from_this,則對_Wptr進行初始化操作,這樣將來調用shared_from_this函數的時候,就能夠通過weak_ptr構造出對應的shared_ptr。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章