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

履歴 編集

class template
<memory>

std::enable_shared_from_this(C++11)

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

#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

処理系

参照