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
クラスの正しい使い方は、
shared_ptr
で管理するクラスが- このクラスをpublic継承して、
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);
}
xxxxxxxxxx
#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
処理系
- Clang: 3.0 ✅
- GCC: 4.3.6 ✅
- ICC: ??
- Visual C++: 2008 (TR1) ✅, 2010 ✅, 2012 ✅, 2013 ✅