当你只有一个this指针的时候,而你又想通过这个this指针得到一个shared_ptr,你就需要用到 enable_shared_from_this 了。
其中 enable_shared_from_this 可以来自boost中的,也来自c++11:
class Y: public enable_shared_from_this<Y>
{
public:
shared_ptr<Y> f()
{
return shared_from_this();
}
}
int main()
{
shared_ptr<Y> p(new Y); // 啊~这里必须先有一个
shared_ptr<Y> q = p->f(); // shared_from_this
assert(p == q);
assert(!(p < q || q < p)); // p and q must share ownership
}
如果你不是返回一个 shared_from_this(),而是 新生成一个 shared_ptr (如下),则在多个智能指针销毁的时候会出现多次删除的错误或者错误的使用一个已经被销毁的指针。
class Y: public enable_shared_from_this<Y>
{
public:
shared_ptr<Y> f()
{
return shared_ptr<Y>(this); // 错误
}
}
原因是,每次从原始指针(this)新生成一个 shared_ptr,则其内部的计数器是单独的,因此该智能指针不知道其他 shared_ptr 的存在,导致另一个shared_ptr 在销毁后该 shared_ptr 还会使用者一个 dangling reference。
For this reason you must never create more than one shared_ptr from the same raw pointer
但是,但是,但是。。。(there is always a but…)
如果 没有 预先为 class Y
创建一个 shared_ptr
,而直接调用了shared_from_this
, 则会抛出 exception。
这是因为 shared_ptr 由两部分组成,如图(effective modern c++):
所有的 shared_ptr 都共享同一个 Control Block,而 shared_from_this
的行为是寻找一个已经存在 Control Block,而不是创建一个(新建一个则意味着又回到了两个shared_ptr来自同一个 raw pointer 的错误),所以,如果 shared_from_this
找不到则会抛出异常了。
因此,在调用 shared_from_this
之前确保已经存在一个shared_ptr
指向该对象。