【问题标题】:Circular Dependencies? [duplicate]循环依赖? [复制]
【发布时间】:2013-12-10 21:30:04
【问题描述】:

好的,我理解前向声明,但在这种情况下我需要在两端调用成员/字段,所以我不能使用它。我试图覆盖 .cpp 文件中的声明(通过包含我需要使用的类的实际标头),但是当我尝试使用它时,我通过前向声明在标头中定义的指针被破坏了。

我该如何解决这个问题?需要代码吗?

【问题讨论】:

  • 您描述的相互依赖关系表明存在设计缺陷。重新审视您的设计并消除这两种类型之间的紧密耦合。
  • SSCCE 会很可爱...sscce.org
  • 好吧,我有一个事件系统。我还有一个 A 类,它包含 B 类对象的指针,并管理该对象。现在我想让 B 类发送事件,包含指向 A 类的指针。因此所有类都需要相互了解(除了 Event 类,它只需要知道 A 类)
  • B 类不需要知道 A 类的类型就可以向它发送事件。使用依赖注入。使 Class A 派生自一个名为“EventReceiver”的类,然后将指向 EventReceiver 的指针存储在 Class B 中。参见the Observer pattern
  • 事件不是由A或B处理的。B类需要知道“事件”。 “事件”需要知道 A 类。A 类需要知道 B 类。

标签: c++ dependencies


【解决方案1】:

如果您是唯一可以访问代码内部的人(例如,当您为自己做一个项目时,独自一人,或分发一个封闭的 .lib/.dll ),并且您确定需要您的类以循环方式包含自己,您始终可以使用抽象基类。

class base{};

class A: public base{
   base *bMember;
};

class B: public base{
   base *aMember;
};

这是一个不好的做法,但如果您需要一个直接的解决方案,它应该就足够了。更好的方法是修复依赖关系或使用单独的基类。

【讨论】:

  • 即使他确实需要这样做,为什么转发声明就足够了?我没有看到抽象基类的意义。
  • 一些较旧的 IDE 倾向于忽略前向声明。当我很久以前用某个版本的 VS 做一个项目时,我遇到了这样的问题。
【解决方案2】:

您需要记住,形成一个指向类的指针只需要该类的声明,而访问该类的成员需要它的定义。所以要解决循环依赖,你可以这样做:

A.hpp

class B;

class A
{
public:
  int foo(B *b);
  int bar();
};

B.hpp

class A;

class B
{
  A *m_a;
public:
  int foo();
  explicit B(A *a) : m_a(a) {}
};

A.cpp

#include "A.hpp"
#include "B.hpp"

int A::foo(B *b)
{
  return 2 * b->foo();
}

int A::bar()
{
  return 42;
}

B.cpp

#include "A.hpp"
#include "B.hpp"

int B::foo()
{
  return m_a->bar();
}

【讨论】:

  • 我试过了,但是指针无效(内存异常)
  • 啊!你是对的,我把一个变量命名错了!
猜你喜欢
  • 2015-01-04
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 2021-10-02
  • 1970-01-01
相关资源
最近更新 更多