【问题标题】:How to structure this without introducing circular includes?如何在不引入循环包含的情况下构建它?
【发布时间】:2020-04-30 14:14:23
【问题描述】:

我正在尝试弄清楚如何构建我的游戏。我想将我的“经理”向下传递,而不是让他们全球化。但是我遇到了一个问题。我的一位经理更新了场景。它需要将应用程序引用传递给场景,因为应用程序包含退出方法。但是我的应用程序持有并更新了这个 SceneManager。所以我的应用程序现在包含 SceneManager,因为它需要更新它,我的 SceneManager 包含应用程序,因为它需要将应用程序引用传递给场景。

基本上Application持有所有的managers,SceneManager将Application引用传递给Scenes,Scenes使用从Applicationreference获得的managers。

// In application
sceneManager.updateScenes(*this);
// In SceneManager
currentScene.update(application)
// In scene
application.getSceneManager().doSomething()

谁能建议我如何优雅地构建我的游戏的这一部分?我知道前向声明,但我想知道是否有无需进行前向声明的解决方案。

我可以使用全局变量,但我不想这样做。

【问题讨论】:

  • 当您传递和存储引用时,标头不需要完整的类定义。不要在标题中包含其他标题;改为使用类的前向声明。在实现文件中包含两个标题是安全的。
  • 你熟悉事件、回调、信号吗?使用其中一种模式允许对象(即SceneManager)向其所有者发出信号,而无需对所有者类型产生硬依赖。 Application 可以有一个SceneManager,并从创建SceneManager 的上下文中为SceneManager 的事件分配回调或事件处理程序。
  • 请注意,我试图避免前向声明,因为我需要在需要引用的所有内容中声明应用程序。 (SceneManager 依赖于 Scene,Scene 需要 Application。Scene 依赖于 GameObject,Gameobject 需要 Application……)我认为这表明我的整个设计是无用的,并且可以通过坚持一些不同的模式来解决。跨度>
  • 如果您不使用前向声明,您仍然必须在需要它的所有内容中定义Application。您也许可以重新设计以尽量减少Applications 的曝光。也许pimpl idiom 是您正在寻找的答案。?

标签: c++ oop architecture


【解决方案1】:

此问题的一个常见(但不是唯一)解决方案是让 Scene 通过 Application 实现的接口与 Application 进行通信,而不是通过直接引用。

这有一个额外的好处,可以更清楚地表达什么场景(和其他依赖项)需要调用。

例如:

interface ISceneHandler {
  void Quit(); // Request that we quit the game.
}

class Application : ISceneHandler {
  private SceneManager sceneManager;

  public Application() {
    // Pass ourself as the handler.
    sceneManager = new SceneManager(this);
  }

  public void Quit() { ... }
}

class SceneManager {
  private ISceneHandler handler;

  public SceneManager(ISceneHandler handler) {
    this.handler = handler;
  }

  public void SomeEvent() {
    this.handler.Quit();
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 2011-10-16
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多