与之前的question相关,我现在有以下一个:
在下一个场景中:
class B;
class A
{
// stuff, methods and so on
B b;
};
class B
{
// stuff, methods and so on
A a;
};
此处我们在A
和B
之间存在循环依赖关系,但此代码格式错误,因为B
是一个不完整的类型。解决方案是通过智能指针将B
指针改为B
。但是添加指针会不必要地增加复杂性和资源消耗,因为你不需要指针!
在之前的question中,我试图通过模板避免使用指针,所以我在类定义了两个类的时候延迟了类的瞬间,但我无法成功地完成它。
避免使用指针是不可能的吗?有没有众所周知的设计来避免循环依赖?
答案 0 :(得分:8)
不可能避免某种形式的引用,例如指针。
当您尝试这样做时,定义中会有无限递归。 A
包含B
,其中包括A
,等等。因此,这两个类都需要无限存储,这显然是荒谬的。
如果您的模型中A
包含B
且B
包含A
,那么这些类似乎无法彼此生活。在这种情况下,也许你只有一个班而不是两个班。
答案 1 :(得分:7)
编译器必须计算B
所需的空间。
它是如何做到的?可以看出,所需空间大小为A
。
但A
的大小是B
的大小。回到原点,编译器必须永远循环才能弄明白。因此它不会编译。
唯一的解决方案是打破这个循环,即使用指针(智能或其他)。
答案 2 :(得分:3)
我认为这不是编译器的主要问题(但它不能这样做),而是设计中的一个问题:数据成员表示所有权。如果A
的数据成员类型为B
,则A
的实例拥有B
的实例。
如果B
同样适用,那么您将获得循环所有权(a
拥有b
而b
拥有a
)或无限期系列a0
拥有b0
拥有a1
拥有b1
.....
因此,您必须表达两种类型中的至少一种,即实例不拥有另一种类型的实例。您可以使用(智能)指针或引用在C ++中执行此操作,或将对象传递给类所需的每个成员函数。