的std ::这样的shared_ptr(std::shared_ptr of this)

2019-06-17 14:23发布

目前我正在努力学习如何使用智能指针。 然而,在做一些实验,我发现了以下情况的,我无法找到一个解决方案satifying:

想象一下,你有B类(子)的对象的A类是父母的一个对象,但都应该知道对方:

class A;
class B;

class A
{
public:
    void addChild(std::shared_ptr<B> child)
    {
        children->push_back(child);

        // How to do pass the pointer correctly?
        // child->setParent(this);  // wrong
        //                  ^^^^
    }

private:        
    std::list<std::shared_ptr<B>> children;
};

class B
{
public:
    setParent(std::shared_ptr<A> parent)
    {
        this->parent = parent;
    };

private:
    std::shared_ptr<A> parent;
};

现在的问题是如何能够类A的对象传递std::shared_ptr本身( this )到其子?

有用于升压共享指针(解决方案获得一个boost::shared_ptrthis ),但如何使用来处理这个std::智能指针?

Answer 1:

还有std::enable_shared_from_this只是为了这个目的。 你继承它,你可以调用.shared_from_this()从类里面。 你也是在这里创造循环依赖可能导致资源泄漏。 这可以通过使用来解决std::weak_ptr 。 所以,你的代码可能是这样的(假设孩子依靠父母的存在,而不是周围的其他方法):

class A;
class B;

class A
    : public std::enable_shared_from_this<A>
{
public:
    void addChild(std::shared_ptr<B> child)
    {
        children.push_back(child);

        // like this
        child->setParent(shared_from_this());  // ok
        //               ^^^^^^^^^^^^^^^^^^
    }

private:     
    // note weak_ptr   
    std::list<std::weak_ptr<B>> children;
    //             ^^^^^^^^
};

class B
{
public:
    void setParent(std::shared_ptr<A> parent)
    {
        this->parent = parent;
    }

private:
    std::shared_ptr<A> parent;
};

但是请注意,调用.shared_from_this()要求, this所拥有std::shared_ptr在呼叫点。 这意味着您不能创建在栈上这样的对象了,而且一般不能调用.shared_from_this()从构造函数或析构函数中。



Answer 2:

你必须在你设计的几个问题,似乎从你误解智能指针的遏制。

智能指针用于声明所有权。 你被宣布双方父母所拥有的所有的孩子打破这一点,也是每个孩子拥有它的父。 这两个不可能是真的。

此外,您在返回一个弱指针getChild() 通过这样做,您声明呼叫者不应该关心的所有权。 现在,这可能是非常有限,而且还这样做,你必须确保,而任何弱指针仍持有有问题的孩子会不会被摧毁,如果你想使用智能指针,它会得到自行整理。

而最后一件事。 通常情况下,当你接受新的实体,通常应接受原始指针。 智能指针可以有自己的含义,父母之间的交换孩子,但对于一般的使用,你应该接受原始指针。



文章来源: std::shared_ptr of this