回答編集履歴

1 update

yohhoy

yohhoy score 6083

2016/10/11 12:01  投稿

thisポインタから`shared_ptr`型(や`std::weak_ptr`型)を取り出す場合は、[`std::enable_shared_from_this`クラステンプレート](http://cpprefjp.github.io/reference/memory/enable_shared_from_this.html)を利用してください。同クラスから[CRTP](https://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E5%A5%87%E5%A6%99%E3%81%AB%E5%86%8D%E5%B8%B0%E3%81%97%E3%81%9F%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3(Curiously_Recurring_Template_Pattern))の形でpublic継承し、`shared_from_this()`メンバ関数を呼び出します。
thisポインタから`std::shared_ptr`型(や`std::weak_ptr`型)を取り出す場合は、[`std::enable_shared_from_this`クラステンプレート](http://cpprefjp.github.io/reference/memory/enable_shared_from_this.html)を利用してください。同クラスから[CRTP](https://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E5%A5%87%E5%A6%99%E3%81%AB%E5%86%8D%E5%B8%B0%E3%81%97%E3%81%9F%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3(Curiously_Recurring_Template_Pattern))の形でpublic継承し、`shared_from_this()`メンバ関数を呼び出します。
```C++
#include <cassert>
#include <vector>
#include <memory>
class Container
 : public std::enable_shared_from_this<Container> {
public:
 std::vector<std::shared_ptr<Container>> children;
 std::weak_ptr<Container> parent;
 Container() {}
 ~Container() = default;
 void addChild(std::shared_ptr<Container> child) {
   children.push_back(child);
   child->parent = shared_from_this();
 }
};
int main()
{
 auto p = std::make_shared<Container>();
 auto c1 = std::make_shared<Container>();
 auto c2 = std::make_shared<Container>();
 p->addChild(c1);
 p->addChild(c2);
 assert(p.use_count() == 1);
}
```
```
なお`shared_ptr<Container>(this);`として強引に`shared_ptr`型を生成するのはNGです。型変換によりコンパイラはごまかせますが、この`shared_ptr`オブジェクトのスコープが切れたときに意図せずデストラクタ`~Container()`を呼び出し、thisオブジェクトが破壊されてしまいます。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る