C++  shared_from_this 資料搜索

關於shared_from_this 查找的資料:ios

1. TcpConnection用到了enable_shared_from_this這個基類,這個基類提供了一個shared_from_this()公用方法可讓子類內部獲取到shared_ptr的對象,用來用在類實現過程當中須要傳遞自身指針的地方。有幾個點須要注意一下:c++

  • 雖然enable_shared_from_this是基類,但它確實在shared_ptr裏面初始化enable_shared_from_this的成員weak_ptr。所以不能在子類的構造方法裏面調用shared_from_this(),由於這個時候weak_ptr仍是空值。
  • 爲何在類的內部不直接使用this指針,由於咱們程序中用shared_ptr來管理指針,若是咱們在類的內部傳遞的過程當中用原始指針,這樣類內部的引用shared_ptr不會察覺到,由於有可能咱們傳進去的時候已經被shared_ptr釋放掉了

2. shared_ptr     enable_shared_from_this函數

一種避免內存泄漏的方式是, always use a named smart pointer variable to hold the result of newthis

shared_ptr<T>  p(new T);spa

boost文檔中首先講了enable_shared_from_this的做用 : The header <boost/enable_shared_from_this.hpp> defines the class template enable_shared_from_this. It is used as a base class that allows a shared_ptr to the current object to be obtained from within a member function.設計

  • enable_shared_from_this<D> 做爲D的基類, 這樣D就繼承了它的兩個public函數:  

    shared_ptr<D> shared_from_this() ;    const shared_ptr<D>  shared_from_this  const ();指針

  • D對象自己是不能夠直接調用 shared_from_this()的, 在boost的代碼設計中, D繼承自 enable_shared_from_this<D> 的 private成員  weak_ptr<D> weak_this_  是從第三方函數調用D._internal_accept_owner(shared_ptr<D> const * Dptr,  D * pD)  來初始化, 而這個第三方函數是在 shared_ptr.hpp中實現的, 且由 shared_ptr<>的構造函數調用(很容易的把this傳過去)
 1 #include <boost/shared_ptr.hpp>
 2 #include <boost/enable_shared_from_this.hpp>
 3 #include <iostream>
 4 
 5 using namespace std;
 6 using namespace boost;
 7 
 8 class WY : public enable_shared_from_this<WY>{
 9 public:
10     WY (int i):i_(i) { cout << "WY's constructor" << endl; }
11 
12     int i (){return i_;}
13     
14     shared_ptr<WY> get_shared_ptr (){
15         cout << "in get_shared_ptr ==> i = " << i_ << endl;
16         return shared_from_this();
17     }
18 private :
19     int i_;
20 };
21 
22 int main ()
23 {
24     WY wy(6);  //這個wy對象實際上它的成員(繼承自enable_shared_from_this<WY>) weak_ptr<WY>, 並有被初始化, 因此調用wy.shared_from_this()會拋錯
25     shared_ptr<WY> ptr(new WY(5));  //這個ptr所持有的WY, 其weak_ptr<WY>, 是初始化過的
26     shared_ptr<WY> p = ptr->shared_from_this();
27     ptr->get_shared_ptr();
28     wy.get_shared_ptr();
29     p = wy.shared_from_this();
30 }

24 行的 wy中的 weak_ptr沒有被初始化, 25行ptr是初始化過的code

程序到28行的時候打印出   in get_shared_ptr  i = 6 以後異常退出, 即只要用 wy調用 shared_from_this 程序即異常退出htm

關於上面第二點中的源代碼剖析是針對 1-46-1來講的, 當我翻看之前版的源碼時, 發現並非這樣實現的, 並沒_internal_accept_owner 這個函數, 因此咱們只需記住的時boost爲外提供的使用方式, 那就是要  shared_ptr<D>  pD的持用的 D, 其中的weak_this_纔是初始化過的, 纔可調用其 shared_from_this, 以這樣的方式   pD->shared_from_this()對象

3. shared_from_this()在一個類中須要傳遞類對象自己shared_ptr的地方使用shared_from_this函數來得到指向自身的shared_ptr,它是enable_shared_from_this<T>的成員函數,返回shared_ptr<T>。
首先須要注意的是這個函數僅在shared_ptr<T>的構造函數被調用以後才能使用。緣由是enable_shared_from_this::weak_ptr並不在enable_shared_from_this<T>構造函數中設置,而是在shared_ptr<T>的構造函數中設置。 

a) 以下代碼是錯誤的:

1 class D:public boost::enable_shared_from_this<D>  
2  {  
3  public:  
4      D()  
5   {  
6          boost::shared_ptr<D> p=shared_from_this();  
7     }  
8 };  

緣由很簡單,在D的構造函數中雖然能夠保證enable_shared_from_this<D>的構造函數已經被調用,但正如前面所說,weak_ptr尚未設置。 
b) 以下代碼也是錯誤的:

 1 class D:public boost::enable_shared_from_this<D>  
 2  {  
 3  public:  
 4      void func()  
 5      {  
 6          boost::shared_ptr<D> p=shared_from_this();  
 7      }  
 8  };  
 9  void main()  
10  {  
11      D d;  
12      d.func();  
13  }  

錯誤緣由同上。 
c) 以下代碼是正確的:

1 void main()  
2  {  
3      boost::shared_ptr<D> d(new D);  
4      d->func();  
5  }  

這裏boost::shared_ptr<D> d(new D)實際上執行了3個動做:
1. 首先調用enable_shared_from_this<D>的構造函數;
2. 其次調用D的構造函數;
3. 最後調用shared_ptr<D>的構造函數。
是第3個動做設置了enable_shared_from_this<D>的weak_ptr,而不是第1個動做。這個地方是很違背c++常理和邏輯的,必須當心。 

結論是:不要在構造函數中使用shared_from_this;其次,若是要使用shared_ptr,則應該在全部地方均使用,不能使用D d這種方式,也決不要傳遞裸指針。

相關文章
相關標籤/搜索