• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    class template
    <memory>

    std::enable_shared_from_this

    namespace std {
      template <class T>
      class enable_shared_from_this;
    }
    

    概要

    enable_shared_from_thisは、shared_ptrで管理しているオブジェクトのthisポインタを、shared_ptrとして扱うことを可能にするためのクラスである。

    thisポインタを単純にshared_ptr<T>(this)としてしまうと、参照カウントが増えず、deleteが2重に呼ばれてしまいバグを引き起こすことになるため、そうならないようにこのクラスを使用してthisを扱う。

    このクラスは、shared_ptrとして管理するクラスの基底クラスとして使用する。このクラスをpublic継承したクラスでpublicメンバ関数shared_from_this()を使用することで、thisを指すshared_ptrオブジェクトを取得できる。

    このクラスを継承する際には、このクラスのテンプレート引数として、派生クラス(このクラスを継承するクラス自身)を指定すること。(このようにテンプレート引数を指定する方法を、CRTP:Curiously Recurring Template Patternと言う)

    正しい使い方と、誤った使い方

    enable_shared_from_thisクラスの正しい使い方は、

    1. shared_ptrで管理するクラスが
    2. このクラスをpublic継承して、
    3. shared_from_this()メンバ関数を使用して、thisを指すshared_ptrオブジェクトを取得する。

    というものだが、これに反して誤った使い方をしてしまう場合がある。以下は、誤った使い方なので、正しい使い方を確認すること。

    • shared_ptrで管理していないクラスオブジェクトに、このクラスを使用するのは間違い。

    struct X : public std::enable_shared_from_this<X> {
      void func() {
        auto self = shared_from_this();  // (2) NG : thisがshared_ptrで管理されていない
      }
    };
    
    auto ptr = new X(/*...*/);  // (1) shared_ptr管理でない場合...
    ptr->func();
    

    protectedメンバ関数

    名前 説明 対応バージョン
    (constructor) コンストラクタ C++11
    (destructor) デストラクタ C++11
    operator= 代入演算子 C++11

    publicメンバ関数

    名前 説明 対応バージョン
    shared_from_this thisポインタをshared_ptrに変換する C++11
    weak_from_this thisポインタをweak_ptrに変換する C++17

    #include <cassert>
    #include <memory>
    
    struct X : public std::enable_shared_from_this<X> {
      std::shared_ptr<X> f()
      {
        // thisを指すshared_ptrオブジェクトを作る
        return shared_from_this();
      }
    };
    
    int main()
    {
      std::shared_ptr<X> p(new X());
      std::shared_ptr<X> q = p->f();
    
      assert(p == q);
    }
    

    出力

    バージョン

    言語

    • C++11

    処理系

    参照