std :: shared_ptr这个

Ica*_*rus 82 c++ this shared-ptr this-pointer

我目前正在尝试学习如何使用智能指针.然而,在做一些实验时,我发现了以下情况,我无法找到一个令人满意的解决方案:

想象一下,你有一个A类的对象是B类对象(孩子)的父对象,但两者都应该互相认识:

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;
};
Run Code Online (Sandbox Code Playgroud)

问题是A类的一个对象如何std::shared_ptr将自身(this)传递给它的孩子?

有Boost共享指针(Get a boost::shared_ptrforthis)的解决方案,但是如何使用std::智能指针处理这个问题?

yur*_*hek 146

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;
};
Run Code Online (Sandbox Code Playgroud)

但请注意,呼叫.shared_from_this()需要在呼叫点this拥有std::shared_ptr.这意味着您不能再在堆栈上创建此类对象,并且通常无法.shared_from_this()在构造函数或析构函数内调用.

  • 感谢您的解释并指出我的循环依赖问题。 (2认同)
  • 考虑到父类通常应该拥有子类的所有权,那么在父类中声明子类的weak_ptr,而子类持有父类的所有权(shared_ptr),这不是很混乱吗?那么现在孩子归谁所有呢? (2认同)

Let*_*_Be 8

您在设计中遇到了一些问题,这些问题似乎源于您对智能指针的误解.

智能指针用于声明所有权.你通过声明父母既拥有所有孩子,又让每个孩子拥有它的父母来打破这一点.两者都不可能是真的.

此外,您将返回一个弱指针getChild().通过这样做,您宣称调用者不应该关心所有权.现在这可能是非常有限的,但是通过这样做,你必须确保有问题的孩子在任何弱指针仍然被保持时不会被破坏,如果你使用智能指针,它将自己整理出来.

最后一件事.通常,当您接受新实体时,通常应该接受原始指针.智能指针对于在父母之间交换孩子有其自己的意义,但是对于一般用法,你应该接受原始指针.