【问题标题】:Correct use of unique_ptr for parent / child relationship正确使用 unique_ptr 进行父/子关系
【发布时间】:2013-07-05 12:49:46
【问题描述】:

我对 C++ 和智能指针比较陌生,因为我主要使用 C#。我在这里遇到了很多关于正确使用 unique_ptrs 的问题,我想我理解智能指针都是关于所有权的,当指针超出范围时,谁将负责删除指针所持有的内存。

也就是说,下面的例子正确吗?父母永远是孩子的主人,管理孩子的一生。但是,如果另一个类需要持有一个孩子,并且总是比孩子活得少,那么该类是否可以持有一个指向孩子的原始指针?

class ChildTypeA;
class ChildTypeB;

class Parent
{
public:
    ChildTypeA* createChildA()
    {
        ChildTypeA *aPtr = new ChildTypeA(/* pass this to constructor */);
        typeAChildren.push_back(std::unique_ptr<ChildTypeA>(aPtr));

        return aPtr;
    }

    ChildTypeB* createChildB()
    {
        ChildTypeB *aPtr = new ChildTypeB(/* pass this to constructor */);
        typeBChildren.push_back(std::unique_ptr<ChildTypeB>(aPtr));

        return aPtr;
    }

    void somethingCalledByChildA()
    {}

    void somethingCalledByChildB()
    {}

private:
    std::vector<std::unique_ptr<ChildTypeA>> typeAChildren;
    std::vector<std::unique_ptr<ChildTypeB>> typeBChildren;
};

class ChildTypeA
{
public:
    ChildTypeA() {} // parameterless constructor purely for single file example
    ChildTypeA(Parent *parent) : owningParent(parent)
    {}

    void notifyParentOfSomethingA()
    {
        owningParent->somethingCalledByChildA();
    }

    void doSomethingOnThisChild()
    {}

private:
    Parent *owningParent;

};

class ChildTypeB
{
public:
    ChildTypeB() {} // parameterless constructor purely for single file example
    ChildTypeB(Parent *parent) : owningParent(parent)
    {}

    void notifyParentOfSomethingB()
    {
        owningParent->somethingCalledByChildB();
    }

private:
    Parent *owningParent;

};

class SomeOtherClassThatWantsAChildAAndWillAlwaysLiveShorterThanChildA
{
public:
    SomeOtherClassThatWantsAChildAAndWillAlwaysLiveShorterThanChildA(ChildTypeA *child) : childNotOwnedByMe(child)
    {}

    void doSomething()
    {  
       childNotOwnedByMe->doSomethingOnThisChild();
    }

private:
    ChildTypeA * childNotOwnedByMe;
};

因此,某处的代码会执行以下操作:

ChildTypeA *a = someInstanceOfParent->createChildA();
auto x = new SomeOtherClassThatWantsAChildAAndWillAlwaysLiveShorterThanChildA(a);

【问题讨论】:

  • 您可能需要考虑使用引用而不是指针。
  • 如果你只是观察一些东西,原始指针就可以完成这项工作。这包括持有指向父级的原始指针的子级。
  • 我确实考虑过将 Parent 引用传递给 ChildA / B,但在这里的另一篇文章中读到,引用类成员可能会出现问题,尤其是在我需要更改 owningParent 时。

标签: c++ unique-ptr


【解决方案1】:

这个例子是正确的,unique_ptr 是关于所有权的,这并不妨碍引用其他类的原始指针,需要记住的是:

1) 使用前检查原始指针。

2) 不要在原始指针上调用delete

【讨论】:

  • 谢谢!最终可能会通过智能指针来理解所有权。
猜你喜欢
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多