【问题标题】:Mutual inclusion with singleton与单例相互包含
【发布时间】:2012-08-09 00:19:23
【问题描述】:

我目前在我的一个项目 (C++) 中存在相互包含的问题。

通常,如果我遇到了相互包含问题,我可以通过前向声明或稍微重新设计类来轻松解决它。但这一次,我被困住了:

我有一个名为 Game 的类,它创建和启动核心游戏系统,其中一个称为 GraphicsSystem。 在 Game 构造函数中,GraphicsSystem 对象被动态创建并存储在 GraphicsSystem* 指针中。看起来像这样:

Game::Game ()
{
    gfxSys = new GraphicsSystem(80, new Camera());
}

现在我的 GraphicsSystem 类需要在某一时刻访问 Game 类的方法以获取存储在 Game 对象中的玩家对象。各自的部分看起来像这样(游戏是单例!):

void GraphicsSystem::handleFrame ()
{
    ElementList elements = Game::instance()->getPlayer()->getEnvironment()->getElements();
}

现在我已经尝试在两个方向上进行前向声明,但这不能满足编译器的要求。我当然也可以将播放器指针放入图形系统,但我真的不想这样做,因为他不属于那里。

有没有什么方法可以解决这个问题,而我不必过多地改变设计?我现在真的很困惑,所以我希望你们能帮助我。

我正在使用 Visual Studio 2010 (Visual C++)。

提前感谢您! 克里斯

【问题讨论】:

  • 您能否详细说明尝试前向声明时发生的情况?还有你的代码文件的结构是什么?我的意思是相关的类在哪些文件中?

标签: c++ singleton circular-reference


【解决方案1】:

在 Game.h 中转发声明 GraphicsSystem。如果需要,请在 GraphicsSystem.h 中包含 Game.h。在 Game.cpp 中包含 Game.h 和 GraphicsSystem.h。在 GraphicsSystem.cpp 中包含 Game.h 和 GraphicsSystem.h。 这应该根据您发布的代码起作用。

【讨论】:

  • 谢谢,我现在将 GraphicsSystem.h 直接包含在 Game.cpp 中的事实修复了它。通常,除了相应的类声明文件(意味着 Game.cpp 中仅包含 Game.h)之外,我从不在 .cpp 中包含另一个头文件。使用前向声明时我应该只在 .cpp 中包含吗?
  • @Christoph 如果在类的实现中必须使用非匹配类(本例中为GraphicsSystem类),则需要包含头文件,无论是否使用转发声明,但是当你做一个前向声明时,你几乎总是必须包含另一个头文件。
【解决方案2】:

在 C++ 中打破循环依赖有两种主要方法。

1) 创建一个“接口”类,其中列出了您的真实类实现的方法以及您的真实类继承自的方法。然后你可以包含它而不是真正的类的声明。

2) Pimpl - 一个类拥有一个指向其真实数据的不透明指针,解决了必须包含成员变量类型声明的问题。

【讨论】:

    【解决方案3】:

    我知道这听起来很狡猾,但是您是否考虑过为已初始化的 Game 类保留一个 global reference

    我知道全局变量是邪恶的等等,我相信很多人会愤怒,但以我个人的经验我已经屈服于单发炎 strong> 使用 Game 类(以及其他),发现有时它根本没有必要。

    你需要问自己的最大问题是“你想保护你的游戏对象免受谁的伤害?,你有什么理由需要 每次都请求一个实例你需要游戏类?我很确定如果你的 Game 对象没有被初始化,你就不会在你的引擎中做很多其他事情无论如何。

    希望这可以帮助您以不同的方式思考问题,即使它没有直接回答您的问题。

    【讨论】:

      猜你喜欢
      • 2021-08-06
      • 2023-03-03
      • 1970-01-01
      • 2012-01-21
      • 2014-09-11
      • 2022-01-04
      • 2010-09-28
      • 1970-01-01
      相关资源
      最近更新 更多