【问题标题】:Avoiding circular dependence?避免循环依赖?
【发布时间】:2013-04-11 17:03:48
【问题描述】:

与之前的question相关,我现在有以下一个:

在接下来的风景中:

class B;

class A
{
   // stuff, methods and so on
   B b;
};

class B
{
   // stuff, methods and so on
   A a;
};

这里我们在AB 之间存在循环依赖关系,但是由于B 是一个不完整的类型,所以这段代码格式不正确。一种解决方案是通过B 的指针更改B,例如通过智能指针。但是添加指针会增加复杂性和不必要的资源消耗,因为您不需要指针!

在之前的question中,我试图通过模板来避免使用指针,所以我在定义了两个类的地方延迟了类的实例化,但是我无法成功。

避免指针是不可能的吗?是否有众所周知的设计来避免循环依赖?

【问题讨论】:

  • 如果它编译了,这甚至没有意义。你说的是A 的实例包含B 的实例,但B 的实例也包含A 的实例。您将需要无限量的内存和无限量的时间来创建这样的对象。也就是说,A 的构造函数和B 的构造函数都会无限递归。
  • 你为什么要避免指针?
  • 你也可以使用引用。
  • std::unique_ptr,以避免讨厌的原始指针。
  • 问问自己,sizeof(A)sizeof(B) 是什么?如果你不能用有限的数字回答这个问题,那么你就有了一个格式错误的类。那是你绝对应该考虑使用指针和引用的时候。

标签: c++ circular-dependency


【解决方案1】:

无法避免某种形式的引用,例如指针。

当您尝试这样做时,定义中有无限递归。 A 包括 B,其中包括 A,以此类推。因此,这两个类都需要无限存储,这显然是无意义的。

如果您确实有一个模型,其中A 包含B 并且B 包含A,那么这些类似乎无法相互独立。在这种情况下,也许你真的只有一门课,而不是两门课。

【讨论】:

  • 我想在这种情况下,这是“可能的”,因为每个字段只有一个,没有其他字段。所以不会倍增。但是,是的,在任何其他情况下它都需要无限的内存。
  • @DyP 当问题没有表明 为什么 OP 想要这样做时,它几乎是最有用的。
  • @DyP 发布 OP 的请求是不可能的是回答 SO 的有效方式。
  • @DyP 你对“是否不可能避免指针?”的回答是什么?我看不到任何其他答案。我不同意你对所提出的问题提出完全不同的答案。
  • @DyP 所以你认为答案是,你不需要使用指针,你可以使用引用?
【解决方案2】:

编译器必须计算出B 所需的空间。

它是如何做到的?计算出所需的空间是A 的大小。

但是A 的大小是B 的大小。回到第一方,编译器必须永远循环才能弄清楚。因此它无法编译。

唯一的解决方案是打破这个循环,即使用指针(智能或其他)。

【讨论】:

    【解决方案3】:

    我认为这主要不是编译器的问题(尽管它不能这样做),而是您的设计中的问题:数据成员表示所有权。如果A 具有B 类型的数据成员,则A 的实例拥有B 的实例。

    如果 B 也是如此,那么您将获得循环所有权(a 拥有 bb 拥有 a)或无限系列的 a0 拥有 b0 拥有a1 拥有 b1 .....

    因此,您必须为这两种类型中的至少一种表示实例不拥有另一种类型的实例。您可以在 C++ 中使用(智能)指针或引用来执行此操作,或者将对象传递给需要它的类的每个成员函数。

    【讨论】:

      猜你喜欢
      • 2013-02-06
      • 2012-02-15
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 2013-04-02
      • 2011-06-16
      • 2023-03-11
      相关资源
      最近更新 更多