スマートポインタboost::weak_ptr詳細


1、boost::weak_ptr概要boost::weak_ptrはboostライブラリに属し、namespace boostに定義され、ヘッダファイル#includeを含めて使用できます.2、boost::weak_ptr詳細インテリジェントポインタboost::scope_ptrとスマートポインタboost::shared_ptrは、すべての単一オブジェクトメモリの管理問題を完全に解決します.どうしてboostが1つ増えたの?ptr、私たちが考えていないケースはありますか?あります.まずboost::weak_ptrはboost::shared_専用ですptrで用意されています.場合によっては、オブジェクトを使用できるかどうかだけに関心を持ち、内部の参照数に関心を持たないことがあります.boost::weak_ptrはboost::shared_ptrの観察者(Observer)オブジェクト、オブザーバー?オブザーバーはどのように理解しますか?オブザーバーはboost::weak_ptrがboost::shared_ptrのみを参照し、その参照カウントを変更しないことを意味します.オブザーバのboost::shared_ptrが失効すると、対応するboost::weak_ptrも失効します.では、なぜこのオブザーバーが必要になるのでしょうか?では、ループ参照から話さなければなりません.参照カウント便利なメモリ管理メカニズムですが、ループリファレンスのオブジェクトを管理できないという大きな欠点があります.サンプルコードは次のとおりです.
 1 #include 
 2 #include 
 3 #include 
 4 
 5 class parent;
 6 class children;
 7 
 8 typedef boost::shared_ptr parent_ptr;
 9 typedef boost::shared_ptr children_ptr;
10 
11 class parent
12 {
13 public:
14     ~parent() { std::cout <<"destroying parent
"
; } 15 16 public: 17 children_ptr children; 18 }; 19 20 class children 21 { 22 public: 23 ~children() { std::cout <<"destroying children
"
; } 24 25 public: 26 parent_ptr parent; 27 }; 28 29 30 void test() 31 { 32 parent_ptr father(new parent()); 33 children_ptr son(new children); 34 35 father->children = son; 36 son->parent = father; 37 } 38 39 void main() 40 { 41 std::cout<<"begin test...
"
; 42 test(); 43 std::cout<<"end test.
"
; 44 }

このプログラムを実行すると、test関数を終了してもparentオブジェクトとchildrenオブジェクトが互いに参照するため、それらの参照カウントはすべて1であり、自動的に解放されず、このときこの2つのオブジェクトはアクセスできません.これはC++の悪名高いメモリ漏れを引き起こした.<1>一般的に、このような循環参照を解除するには、以下の3つの実行可能な方法がある:1.最後のリファレンスしか残っていない場合は、ループリファレンスを手動で破ってオブジェクトを解放する必要があります.2.parentの生存期間がchildrenの生存期間を超えると、childrenは通常のポインタを使用してparentを指すように変更される.3.弱い参照を使用するスマートポインタは、この循環参照を破る.この3つの方法はいずれも可能であるが,方法1と方法2はプログラマが手動で制御する必要があり,面倒でエラーが発生しやすい.次に、3つ目の方法とboostの弱い参照のスマートポインタboost::weak_ptr. <2>強引用と弱引用とは?強い引用とは、引用されたオブジェクトが生きている場合、この引用も存在する(つまり、少なくとも1つの強い参照がある限り、このオブジェクトは解放されない).boost::share_ptrは強い参照である.相対的に弱い参照は、参照されたオブジェクトが生きている間に必ずしも存在しない.それ自体が存在する場合の参照である.弱い参照は、そのオブジェクトの参照数を変更しない.これは、弱い参照が正しくないことを意味するオブジェクトのメモリを管理します.機能的には通常のポインタと似ていますが、弱いリファレンスは、管理されているオブジェクトが解放されたかどうかを検出し、不正なメモリへのアクセスを回避することができます.boost::weak_ptr boost::weak_ptrはboostが提供する弱い参照のスマートポインタであり、その声明は以下のように簡略化することができる.
 1 namespace boost 
 2 {
 3 template<typename T> class weak_ptr
 4 {
 5 public:
 6     template <typename Y>
 7     weak_ptr(const shared_ptr& r);
 8 
 9     weak_ptr(const weak_ptr& r);
10     
11     ~weak_ptr();
12 
13     T* get() const; 
14     bool expired() const; 
15     shared_ptr lock() const;
16 }; 
17 }

見えますboost::weak_ptrはboost::share_からptrまたは別のboost::weak_ptr変換により、オブジェクトのメモリ管理を行うのは、その強い参照のboost::share_ptr. boost::weak_ptrは、管理オブジェクトへのアクセス手段を提供するだけです.boost::weak_ptrには、管理対象オブジェクトへの基本アクセス機能(get()関数による)のほか、2つの一般的な機能関数があります.1.expired()は、管理されているオブジェクトが解放されたかどうかを検出するために使用されます.2.lock()は、管理対象オブジェクトの強い参照ポインタを取得するために使用されます.<3>boost経由::weak_ptrはループ参照を破る弱参照は参照カウントを変更しないため、通常のポインタと同様に、ループ参照の一方を弱参照で使用すればループ参照を解除することができる.上記の例ではchildrenの定義を次のように変更すれば、ループ参照を解除できます.
1 class children
2 {
3 public:
4     ~children() { std::cout <<"destroying children
"
; } 5 6 public: 7 boost::weak_ptr parent; 8 };

【3】boost::weak_ptrまとめ弱いリファレンスポインタで効率的にループリファレンスを解除できるが、この方式はプログラマがループリファレンスが発生することを予見できる場合に使用する必要があり、これはコンパイル期間の解決策にすぎないとも言える.シーケンスが実行中にループリファレンスが発生した場合、メモリが漏洩することになる.したがって、スマートポインタを使用すればメモリの漏洩を防ぐことができると考えられます.結局、C++にとって、ゴミ回収メカニズムがないため、メモリ漏れはプログラマー一人一人にとって非常に頭が痛い問題です.