shared_ptr vs unique_ptr 用于 类 和儿童

shared_ptr vs unique_ptr uses in classes and children

我一直在关注智能指针的使用,并努力思考它的最佳用途。我已经阅读了很多文章,但我对在下面的示例中使用哪篇文章感到困惑。我已经包含了一个 shared_ptrunique_ptr 示例来展示我正在努力完成的事情:

class A
    public:  
        A();
    private:
        unique_ptr<B> ptrB;

    unique_ptr<SomeObject> ptrUnique;
    shared_ptr<SomeObject> ptrShared;

    A::A()
    {
        ptrB(new B());

        ptrUnique(new SomeObject());
        ptrB->PassUnique(ptrUnique);

        ptrShared(new SomeObject());
        ptrB->PassShared(ptrShared);
    }

class B:
    public:
        void PassUnique(unique_ptr<SomeObject> &ptr_unique);
        void PassShared(weak_ptr<SomeObject> &ptr_weak);
        void DoSomething();
    private:
        unique_ptr<SomeObject> ptrUnique;
        weak_ptr<SomeObject> ptrWeak;

    B::PassUnique(unique_ptr<SomeObject> &ptr_unique)
    {
        ptrUnique = ptr_unique;
    } 

    B::PassShared(weak_ptr<SomeObject> &ptr_weak)
    {
        ptrWeak = ptr_weak;
    }

    B::DoSomething()
    {
        ptrUnique->SomeMethod();

        shared_ptr<SomeObject> ptr1 = ptrWeak.lock();
        ptr1->SomeMethod();
    }

SomeObject class 可以是任何 class。一个很好的例子是我从父 class A 传递给多个 class 的数据库句柄,例如 B。如果它存在,则从 B 传递给 C。我的问题是,如果我传递一个 unique_ptr 作为参考,将设置例如 B:PassUnique 中的 ptrUnqiue = ptr_unique 创建一个副本,然后是不正确的?还是应该通过 shared_ptr 完成?这种理解使我对智能指针感到困惑,希望得到澄清。

答案基本上就是 A、B and/or C 中指针的生命周期。将其视为范围,[A...a)、[B...b) 和[C...c).如果 [B...b) 总是在 [A...a) 内并且 [C...c) 总是在 [B...b) 内,它们就像俄罗斯套娃等级一样,然后向下传递 ref- to-ptr 没问题。如果范围重叠并且变化很大,所以你不能真正控制最后一个 ptr 的销毁位置和对象将被删除,你必须使用 shared_ptr.

好吧,这是一辈子的问题。您需要 SomeObject 才能比 A 长寿吗? B 是否在此上下文之外发送或正在使用?你必须决定你的对象何时死亡。如果您认为 SomeObject 仅存在于此上下文中,我会建议 A 成为所有者,因为它分配资源,并成为指向 SomeObject 的原始指针。我看起来像这样:

class A
   public:  
     A();
   private:
     unique_ptr<B> ptrB;

     unique_ptr<SomeObject> ptrUnique;
};

A::A()
{
  ptrB(new B());

  ptrUnique(new SomeObject());
  ptrB->PassUnique(*ptrUnique);
}

class B:
  pubic:
    void PassUnique(SomeObject& obj);
    void DoSomething();
  private:
    SomeObject* ptrUnique;
};

B::PassUnique(SomeObject& obj)
{
   ptrUnique = &obj;
} 

B::DoSomething()
{
   ptrUnique->SomeMethod();
}

没有

ptrUnique = ptr_unique;

如果您需要在此结构之外使用和拥有 SomeObject,请像您一样使用 std::shared_ptr。您的 std::shared_ptr 代码没有错误。