boost::enable_shared_from_この解析
3369 ワード
なぜboost::enable_が必要なのかshared_from_this?
この2つのコードには違いがないように見えます.しかし、プログラムの中にはcatのメンバーメソッドのようにcatのraw pointerだけがありますが、shared_を利用したいと思っています.ptrの自動delete特性は、複数のshared_が存在するため、自分で防止したくないptrは、同じcatオブジェクトdeleteに対して複数回危険である.つまり複数shared_ptrは同じカウンタを共有します.このときboost::enable_shared_frome_これは便利になりました.
boost::enable_shared_from_この原理
実はboost::enableを継承しています.shared_from_このクラス、本当のmagicはそれを作成した最初のshared_です.ptrインスタンスの場合.shared_ptrはboost::enable_を反転しますshared_from_これは_internal_accept_ownerメソッド.
class cat{};
shared_ptr<cat> p(new cat);
shared_ptr<cat> p2(p);
class cat:public boost::enable_shared_frome_this{};
shared_ptr<cat> p(new cat);
shared_ptr<cat> p2=p->shared_from_this();
この2つのコードには違いがないように見えます.しかし、プログラムの中にはcatのメンバーメソッドのようにcatのraw pointerだけがありますが、shared_を利用したいと思っています.ptrの自動delete特性は、複数のshared_が存在するため、自分で防止したくないptr
struct A;
void f(shared_ptr<A> const&) {...}
struct A: public enable_shared_from_this<A>
{
void a_f()
{
// you need to call f() here passing itself as a parameter
f(shared_from_this());
}
};
shared_ptr<A> a_ptr(new A());
a_ptr->a_f(); // in inner call to f() will be used temporary shared_ptr<A>
// that uses (shares) the same reference counter as a_ptr
boost::enable_shared_from_この原理
実はboost::enableを継承しています.shared_from_このクラス、本当のmagicはそれを作成した最初のshared_です.ptrインスタンスの場合.shared_ptrはboost::enable_を反転しますshared_from_これは_internal_accept_ownerメソッド.
template<class T> class enable_shared_from_this
{
protected:
enable_shared_from_this()
{
}
enable_shared_from_this(enable_shared_from_this const &)
{
}
enable_shared_from_this & operator=(enable_shared_from_this const &)
{
return *this;
}
~enable_shared_from_this()
{
}
public:
shared_ptr<T> shared_from_this()
{
shared_ptr<T> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
shared_ptr<T const> shared_from_this() const
{
shared_ptr<T const> p( weak_this_ );
BOOST_ASSERT( p.get() == this );
return p;
}
public: // actually private, but avoids compiler template friendship issues
// Note: invoked automatically by shared_ptr; do not call
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
{
if( weak_this_.expired() )
{
weak_this_ = shared_ptr<T>( *ppx, py );
}
}
private:
mutable weak_ptr<T> weak_this_;
};
// , , 。 shared_ptr :
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
{
boost::detail::sp_enable_shared_from_this( this, p, p );
}
template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
{
if( pe != 0 )
{
pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
}
}