boost::enable_shared_from_thisの使いかた

そのobjectのaddress(つまりthis)をboost::shared_ptrとして非static member関数で使用したいとき、そのままthisからboost::shared_ptrを生成すると、そのobjectがdynamic storage durationである場合はいいですが、そうでなく、automatic storage durationだったり、thread storage durationだったり、static storage durationだったりした場合はdestructorが2度呼ばれることになるので、上手くいきません。こういうときはboost::enable_shared_from_thisを使用します。

#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>

class hoge:
  public boost::enable_shared_from_this < hoge >
  {
  public:
    ~hoge () throw ()
      {
      }

    int fuga () const
      {
        return member_fuga;
      }

    boost::shared_ptr < hoge > shared_this () const
      {
        return boost::shared_from_this ();
      }

    static boost::shared_ptr < hoge > create ( int parameter_fuga )
      {
        return boost::shared_ptr < hoge > ( new hoge ( parameter_fuga ) );
      }

  private:
    int member_fuga;

    hoge ( int parameter_fuga ):
      member_fuga ( parameter_fuga )
      {
      }
  };

このように、objectのaddressをboost::shared_ptrとして扱いたいclassをboost::enable_shared_from_this < (当該class) >からpublic継承します。

この例のclassの場合、constructorをprivateにし、static member関数createにのみobjectの生成を許しています。非static member関数shared_thisは、そのobjectのaddressをboost::shared_ptrとして返します。boost::shared_from_thisはclass template boost::enable_shared_from_thisの非static member関数で、thisからboost::shared_ptrを生成し、返します。

boost::shared_ptrで管理されていないobjectがboost::shared_from_thisを呼び出したときは例外が送出されるので、boost::shared_from_thisを使用すると、実質的にobjectがboost::shared_ptrで管理されていることを強制します。