我想定义两个类 A 和 I,使其对象尊重这种关系:
i1 -----------a1
|------a2
|----a3
为了满足这些条件, 我将这两个类声明如下:
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()
{
}
问题:
当删除类 I 的实例 i 时,如果必须删除类 A,则所有附加实例 a 也必须删除: 如何在I的析构函数中设置这个机制?
当类A的实例a被删除时,被删除的类A的a所指向的类I的实例i仍然被其他实例a所指向A 类。 如何确保一旦删除了类 A 的所有实例 a,类 I 的实例 i 仍然可以存在,即使A 的实例 a 不指向它?
A
不应该有 shared_ptr
到 I
,因为 A
不控制 I
的生命周期。一个非拥有的原始指针就足够了。
按照您的描述,所有权关系很简单 -
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));
}
};