我碰到enable_shared_from_this跑一边读Boost.Asio的例子和阅读,我还是失去了应如何正确地使用的文档后。有人可以给我使用这个类时的一个例子和/或与解释是有道理的。

有帮助吗?

解决方案

它可以让你得到一个有效的shared_ptr实例this,当你已经是this。没有它,你就没有得到一个shared_ptrthis,除非你已经有一个作为成员的方式。从enable_shared_from_this的升压文档本示例的:

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,即使它没有构件实例。需要注意的是,你不能简单地做到这一点:

class Y: public enable_shared_from_this<Y>
{
public:

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

在共享指针,该返回将具有从“正确”的一个不同的引用计数,并且将它们中的一个将最终失去并保持当对象被删除悬挂参考。

enable_shared_from_this已成为C ++ 11标准部分。您也可以从那里,以及从升压得到它。

其他提示

从上弱指针布斯博士文章中,我认为本实施例中更易于理解(来源: HTTP:// drdobbs的.com / CPP / 184402026 ):

...这样的代码将无法正常工作:

int *ip = new int;
shared_ptr<int> sp1(ip);
shared_ptr<int> sp2(ip);

无论两个shared_ptr对象知道其他的,所以既会尝试释放它们的资源被破坏时。这通常会导致问题。

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

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对象sp1拥有新分配的资源。成员函数S::dangerous内的代码不知道有关shared_ptr对象,所以它返回shared_ptr对象是从sp1不同。复制新shared_ptr对象sp2没有帮助;当sp2超出范围,这将释放资源,并且当sp1超出范围,它将再次释放资源。

要避免这个问题的方法是使用类模板enable_shared_from_this。模板需要一个模板类型参数,该参数是定义托管资源类的名称。这个类必须反过来,公开从模板导出;像这样:

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对象所拥有。这将无法工作:

int main()
{
   S *p = new S;
   shared_ptr<S> sp2 = p->not_dangerous();     // don't do this
}

下面是我的解释,从螺母和螺栓的角度(顶端回答没有“点击”与我)。 *请注意,这是调查与Visual Studio的2012年或许其他编译器实现enable_shared_from_this不同的shared_ptr的和enable_shared_from_this源的结果... *

enable_shared_from_this<T>增加了一个私人weak_ptr<T>实例T其保持为T的实例 '的一个真正的参考计数'。

所以,当首次创建shared_ptr<T>到一个新T *,即T *的内部的weak_ptr获取与为1的引用计数初始化新shared_ptr基本上背靠此weak_ptr

T然后可以在它的方法,呼叫shared_from_this获得shared_ptr<T>其的的一个实例备份到相同的内部存储的参考计数即可。这样,你总是有一个地方T*的裁判计数存储,而非使用多个shared_ptr情况下,不知道对方,彼此相信他们是负责裁判计数shared_ptrT并删除它时,他们的REF-计数达到零。

请注意,使用一个boost :: intrusive_ptr不存在这个问题。 这往往是一个更方便的方法来解决这个问题。

这正是在C + + 11以后相同的:它是使返回this作为共享自指针this给你一个原始指针的能力

在其它字,它允许打开这样的代码

class Node {
public:
    Node* getParent const() {
        if (m_parent) {
            return m_parent;
        } else {
            return this;
        }
    }

private:

    Node * m_parent = nullptr;
};           

到该:

class Node : std::enable_shared_from_this<Node> {
public:
    std::shared_ptr<Node> getParent const() {
        std::shared_ptr<Node> parent = m_parent.lock();
        if (parent) {
            return parent;
        } else {
            return shared_from_this();
        }
    }

private:

    std::weak_ptr<Node> m_parent;
};           

另一种方式是一个weak_ptr<Y> m_stub成员添加到class Y。然后写:

shared_ptr<Y> Y::f()
{
    return m_stub.lock();
}

有用的,当你不能改变你是从(例如延长别人的库)派生类。不要忘了初始化成员,例如通过m_stub = shared_ptr<Y>(this),其即使在一个构造是有效的。

有确定的,如果有更多的短截线像这样的在继承层次结构中,也不会阻止该对象的破坏。

修改作为正确地指出通过用户nobar,代码会破坏ý对象时分配完成和临时变量被破坏。因此,我的答案是不正确。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top