首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >`enable_shared_from_this`的用处是什么?

`enable_shared_from_this`的用处是什么?
EN

Stack Overflow用户
提问于 2009-04-03 09:46:07
回答 4查看 104.5K关注 0票数 386

我在阅读Boost.Asio示例时遇到了enable_shared_from_this,在阅读了文档之后,我仍然不知道应该如何正确使用它。谁能给我举个例子,解释一下什么时候使用这个类是有意义的。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-04-03 02:00:52

它使您能够将一个有效的shared_ptr实例转换为this,而您所拥有的只有this。如果没有它,您将无法获得thisshared_ptr,除非您已经拥有一个成员身份。boost documentation for enable_shared_from_this中的此示例

代码语言:javascript
复制
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();
    assert(p == q);
    assert(!(p < q || q < p)); // p and q must share ownership
}

即使方法f()没有成员实例,它也会返回一个有效的shared_ptr。请注意,您不能简单地这样做:

代码语言:javascript
复制
class Y: public enable_shared_from_this<Y>
{
public:

    shared_ptr<Y> f()
    {
        return shared_ptr<Y>(this);
    }
}

这个返回的共享指针将有一个与“正确的”不同的引用计数,当对象被删除时,其中一个将丢失并持有一个悬空的引用。

enable_shared_from_this已成为C++ 11标准的一部分。你也可以从那里获得它,也可以从boost获得。

票数 394
EN

Stack Overflow用户

发布于 2011-04-05 15:00:07

从Dobbs博士关于弱指针的文章中,我认为这个例子更容易理解(来源:http://drdobbs.com/cpp/184402026):

像这样的...code将无法正常工作:

代码语言:javascript
复制
int *ip = new int;
shared_ptr<int> sp1(ip);
shared_ptr<int> sp2(ip);

这两个shared_ptr对象都不知道对方,所以当它们被销毁时,它们都会尝试释放资源。这通常会导致问题。

类似地,如果一个成员函数需要一个拥有被调用对象的shared_ptr对象,它不能只动态创建一个对象:

代码语言:javascript
复制
struct S
{
  shared_ptr<S> dangerous()
  {
     return shared_ptr<S>(this);   // don't do this!
  }
};

int main()
{
   shared_ptr<S> sp1(new S);
   shared_ptr<S> sp2 = sp1->dangerous();
   return 0;
}

这段代码与前面的示例具有相同的问题,尽管形式更为微妙。在构造时,shared_ptr object sp1拥有新分配的资源。成员函数S::dangerous中的代码不知道该shared_ptr对象,因此它返回的shared_ptr对象与sp1不同。将新的shared_ptr对象复制到sp2没有任何帮助;当sp2超出作用域时,它将释放资源,而当sp1超出作用域时,它将再次释放资源。

避免这个问题的方法是使用类模板enable_shared_from_this。该模板接受一个模板类型参数,该参数是定义托管资源的类的名称。反过来,该类必须从模板中公开派生;如下所示:

代码语言:javascript
复制
struct S : enable_shared_from_this<S>
{
  shared_ptr<S> not_dangerous()
  {
    return shared_from_this();
  }
};

int main()
{
   shared_ptr<S> sp1(new S);
   shared_ptr<S> sp2 = sp1->not_dangerous();
   return 0;
}

执行此操作时,请记住调用shared_from_this的对象必须属于shared_ptr对象。这是行不通的:

代码语言:javascript
复制
int main()
{
   S *p = new S;
   shared_ptr<S> sp2 = p->not_dangerous();     // don't do this
}
票数 233
EN

Stack Overflow用户

发布于 2012-06-13 21:25:41

请注意,使用boost::intrusive_ptr不会遇到此问题。这通常是解决这个问题的一种更方便的方法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/712279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档