shared_ptr 和 unique_ptr:关于具体案例的问题

问题描述 投票:0回答:2

我想定义两个类 A 和 I,使其对象尊重这种关系:

i1 -----------a1
  |------a2
  |----a3
  • 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();
}

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

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

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

A::~A()
{
}

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

I::~I()
{

}

问题:

  1. 当删除类 I 的实例 i 时,如果必须删除类 A,则所有附加实例 a 也必须删除: 如何在I的析构函数中设置这个机制?

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

c++ shared-ptr smart-pointers unique-ptr
2个回答
1
投票

A
不应该有
shared_ptr
I
,因为
A
不控制
I
的生命周期。一个非拥有的原始指针就足够了。


1
投票

按照您的描述,所有权关系很简单 -

I
A
对象的唯一所有者。
A
I
没有任何所有权,而且,它的生命周期被定义为始终比拥有它的
I
对象短。

因此,一种解决方案是让

I
保留
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));
        }
};
© www.soinside.com 2019 - 2024. All rights reserved.