this
ポインタをstd::shared_ptr
として取得するための機能として、std::enable_shared_from_this
基本クラスとそのメンバ関数shared_from_this()
があります。
std::enable_shared_from_this
から派生したクラスのオブジェクトをnew
してshared_ptr
のコンストラクタに渡すと、そのオブジェクトのthis
がshared_ptr
として取得できるようになります。
しかし、以下のように同じポインタから複数のshared_ptr
オブジェクトを作った場合に、shared_from_this()
で返されるshared_ptr
がどのオブジェクトを指すのか規定されていませんでした。
#include <memory> using namespace std; int main() { struct X : public enable_shared_from_this<X> { }; auto xraw = new X; shared_ptr<X> xp1(xraw); // #1 { shared_ptr<X> xp2(xraw, [](void*) { }); // #2 } xraw->shared_from_this(); // #3 }
実装によっては、 #3 がxp1
を指す場合もあれば、xp2
を指す場合もありました。xp2
を指す場合は、shared_from_this()
の再束縛が行われることを意味します。
C++1zでは、shared_from_this()
が再束縛されないことが既定されます(この場合はxp1
を指し続けます)。また、this
を束縛する動作がスレッドセーフではないことも明記されます。
元々未規定だった動作ですが、xp2
を指すことを期待していたプログラムは動作しなくなる可能性があるので注意してください。
また、再束縛されない仕様を明確にすることを主な目的として、std::enable_shared_from_this
クラスに、weak_ptr
のthis
を返すweak_from_this()
メンバ関数が追加されます。
参照
お断り
この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。