shared_ptr 和 unique_ptr:有关特定情况的问题

Rap*_*l10 -1 c++ smart-pointers shared-ptr unique-ptr

我想定义两个类A,并I以它们的对象尊重这种关系的方式:

i1 -----------a1
  |------a2
  |----a3
Run Code Online (Sandbox Code Playgroud)
  • 该类的一个实例I指向该类的零个、一个或多个实例A

  • 类的一个实例A仅指向该类的一个实例I

  • 类的实例I可以没有任何类的实例A,但类的实例必须“附加”A类的实例。I

为了满足这些条件,我将这两个类声明如下:

class I;
class A
{
    private:
        std::string as;
        std::shared_ptr<I> iA;        
    public:
        A(std::string aTxt);
        A();
        ~A();
};

class I
{
   private:
       std::string ip;
       std::vector<std::unique_ptr<A>> as;
       friend class A;
   public:
       I(std::string i);
       ~I();
};
Run Code Online (Sandbox Code Playgroud)

在源文件中,我以这种方式定义了这两个类:

A::A(std::string aText)
{
    as = aText;
}

A::A()
{
    as = "";
}

A::~A()
{
}

I::I(std::string i)
{
    ip = i;
}

I::~I()
{

}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 当删除i类的实例时,必须删除该类的所有附加实例。如何在 的析构函数中设置这个机制?IaAI

  2. a当类的实例A被删除时,它所指向i的类的实例仍然被该类的其他实例所指向。如何确保一旦类的所有实例都被删除,类的实例仍然可以存在,即使没有实例指向它?IaAaAiIA

Yks*_*nen 5

按照您的描述,所有权关系很简单 -IA对象的唯一所有者。A没有任何所有权,I而且,它被定义为总是比I拥有它的对象的生命周期短。

因此,一种解决方案是保留Ia std::vector<std::unique_ptr<A>>(或者最好是std::vector<A>如果A不是多态的)并A接受指向I构造函数的原始指针。

class I;
class A
{
    private:
        I* iA;        
    public:
        explicit A(I* ownerI) : iA{ownerI} {}
        // no default constructor - you don't want to create invalid objects with no `iA` pointer
        // no user declared destructor - default one is perfectly fine
};

class I
{
   private:
        std::vector<A> as;
        std::vector<std::unique_ptr<A>> polymorphicAs;
   public:
        // no user-declared destructor - default one will do correct things with either 
        //std::vector<A> and std::vector<std::unique_ptr<A>>

        void foo() {
            as.emplace_back(this);
            polymorphicAs.push_back(std::make_unique<A>(this));
        }
};
Run Code Online (Sandbox Code Playgroud)