enable_shared_from_this
5935 ワード
enable_shared_from_this(転載)
C++では自分でメモリを処理する必要がありますが、少し処理が適切でないと、非常に憂鬱なメモリ漏れの問題があります.
幸いなことに、C++では強力なスマートポインタ、すなわちsmartが発売されています.ptr、本稿ではsmartを少し紹介します.ptr、そして具体的にshared_ptrとweak_ptr、特にenable_shared_from_thisとshared_from_this
標準ライブラリのauto_を除くptr以外
boostまたはtr 1のsmart_ptrは主に次のようなものがあります scoped_ptr scoped_array shared_ptr shared_array intrusive_ptr weak_ptr
これらの中で最も理解しにくいのはweakを総合的に応用したことです.ptrとshared_ptrのenable_shared_from_このクラスにはメンバー関数shared_が定義されていますfrom_これは、shared_を返します.ptr .この関数はshared_のみですptrのコンストラクション関数が呼び出されてから使用できます.なぜならenable_shared_from_this::weak_ptrは、コンストラクション関数に設定されるのではなく(ここでのコンストラクション関数とは、タイプTのコンストラクション関数を指す)、shared_ptrのコンストラクション関数に設定される(ここでのコンストラクション関数とは、タイプshared_ptrのコンストラクション関数を指す).
次のコードで、
Cppコード #include #include #include #include #include using namespace std; struct Ansible : public boost::enable_shared_from_this { boost::shared_ptr get_shared() { boost::shared_ptr r(this); return r; } ~Ansible() { cout<<"Destructor"< } }; int main(int argc,char* argv[]) { boost::shared_ptr a(new Ansible); Ansible& r = *a; //boost::shared_ptr b = r.get_shared(); boost::shared_ptr b = r.shared_from_this(); cout<<"Reference Number "< return 0; }
shared_を使用しない場合from_this()メンバー関数は、aとbのuse_を出力します.count()はすべて1で、それから2回のタイプAnsibleの構造関数を呼び出して、もしこのメンバー関数を追加したら、aとbのuse_count()出力は2であり,Ansibleの構造関数を1回呼び出すだけである.なぜならenable_shared_from_この中はshared_ptrの時にweakを構築しましたptrクラス、weak_ptrは監視のみで、参照カウントは増加しません
(以下、転載:http://huyuguang1976.spaces.live.com/blog/cns!2A9E272E3C33AFF1!185.entry )
次のコードは間違っています.
class D:public boost::enable_shared_from_this
{
public:
D()
{
boost::shared_ptr p=shared_from_this();
}
};
理由は簡単で、Dの構造関数ではenable_が保証されていますがshared_from_thisのコンストラクション関数が呼び出されましたが、前述したようにweak_ptrはまだ設定されていません.
次のコードもエラーです.
class D:public boost::enable_shared_from_this
{
public:
void func()
{
boost::shared_ptr p=shared_from_this();
}
};
void main()
{
D d;
d.func();
}
エラーの原因は同じです.
次のコードが正しいです.
void main()
{
boost::shared_ptr d(new D);
d->func();
}
ここでboost::shared_ptrd(new D)は実際に3つの動作を実行した:まずenable_を呼び出すshared_from_thisのコンストラクション関数;次にDのコンストラクタを呼び出す.最後にshared_を呼び出すptrのコンストラクション関数.3番目のアクションにenableが設定されています.shared_from_こののweak_ptrは、1番目の動作ではありません.ここはc++の常識と論理に反しているので、気をつけなければなりません.
結論として、構造関数でshared_を使用しないでください.from_this ;次にshared_を使用する場合ptrは,すべての場所で使用すべきであり,D dという方式は使用できず,裸のポインタも決して渡さない.別解::::struct X
{
boost::shared_ptr getX()
{
boost::shared_ptr r ;//????実装方法
return r;
}
};
Xのスマートポインタを得るには、オブジェクトポインタがshared_を受けるだけです.ptr保護に基づいて、例えば以下のようにする.
void test_X()
{
{
X x;
boost::shared_ptr px = x.getX();//エラー
}
{
X* x = new X();
boost::shared_ptr px = x->getX();//エラー
}
{
boost::shared_ptr x (new X());
boost::shared_ptr px = x->getX();//正しい
}
}
C++では自分でメモリを処理する必要がありますが、少し処理が適切でないと、非常に憂鬱なメモリ漏れの問題があります.
幸いなことに、C++では強力なスマートポインタ、すなわちsmartが発売されています.ptr、本稿ではsmartを少し紹介します.ptr、そして具体的にshared_ptrとweak_ptr、特にenable_shared_from_thisとshared_from_this
標準ライブラリのauto_を除くptr以外
boostまたはtr 1のsmart_ptrは主に次のようなものがあります
これらの中で最も理解しにくいのはweakを総合的に応用したことです.ptrとshared_ptrのenable_shared_from_このクラスにはメンバー関数shared_が定義されていますfrom_これは、shared_を返します.ptr
次のコードで、
Cppコード
#include <iostream> #include <string> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <boost/enable_shared_from_this.hpp> using namespace std; struct Ansible : public boost::enable_shared_from_this<Ansible> { boost::shared_ptr<Ansible> get_shared() { boost::shared_ptr<Ansible> r(this); return r; } ~Ansible() { cout<<"Destructor"<<endl; } }; int main(int argc,char* argv[]) { boost::shared_ptr<Ansible> a(new Ansible); Ansible& r = *a; //boost::shared_ptr<Ansible> b = r.get_shared(); boost::shared_ptr<Ansible> b = r.shared_from_this(); cout<<"Reference Number "<<a.use_count()<<" "<<b.use_count()<<endl; return 0; }
shared_を使用しない場合from_this()メンバー関数は、aとbのuse_を出力します.count()はすべて1で、それから2回のタイプAnsibleの構造関数を呼び出して、もしこのメンバー関数を追加したら、aとbのuse_count()出力は2であり,Ansibleの構造関数を1回呼び出すだけである.なぜならenable_shared_from_この中はshared_ptr
(以下、転載:http://huyuguang1976.spaces.live.com/blog/cns!2A9E272E3C33AFF1!185.entry )
次のコードは間違っています.
class D:public boost::enable_shared_from_this
{
public:
D()
{
boost::shared_ptr
}
};
理由は簡単で、Dの構造関数ではenable_が保証されていますがshared_from_this
次のコードもエラーです.
class D:public boost::enable_shared_from_this
{
public:
void func()
{
boost::shared_ptr
}
};
void main()
{
D d;
d.func();
}
エラーの原因は同じです.
次のコードが正しいです.
void main()
{
boost::shared_ptr
d->func();
}
ここでboost::shared_ptr
結論として、構造関数でshared_を使用しないでください.from_this ;次にshared_を使用する場合ptrは,すべての場所で使用すべきであり,D dという方式は使用できず,裸のポインタも決して渡さない.別解::::struct X
{
boost::shared_ptr
{
boost::shared_ptr
return r;
}
};
Xのスマートポインタを得るには、オブジェクトポインタがshared_を受けるだけです.ptr保護に基づいて、例えば以下のようにする.
void test_X()
{
{
X x;
boost::shared_ptr
}
{
X* x = new X();
boost::shared_ptr
}
{
boost::shared_ptr
boost::shared_ptr
}
}