8

几个月前,我创建了一个名为 Vexed 的游戏的 C# 项目。现在我正在创建一个俄罗斯方块,但在 C++ 中。基本上我想使用我在另一个项目中使用的相同逻辑,有点像这样:

我创建了一个名为“游戏”的类,其中包含有关游戏的所有信息。它有它的方法、变量和一切。然后,我创建了一个名为“PublicInstances”或类似名称的静态类,并在该类中声明了如下内容:

static class PublicInstances
{
    public static Game vexedGame = new Game(); //This is C# and works.
}

那时它使用起来非常简单,因为我对游戏所做的任何更改都保存在我的类的静态实例中,我可以在项目的任何地方访问它。我想知道如何用 C++ 准确地做到这一点,以创建我的类 Game 的公共或全局实例,以便我可以访问它并在任何地方更改它,并在我的项目的任何表单或类中更新所有内容。我将衷心感谢您的帮助。

// 对不起,如果我的英语不是最好的^^

4

1 回答 1

10

重新审视和总结

选项1

您可以简单地声明和定义 Game 对象的全局实例。在头文件中,例如game.h:

extern Game globalGameObj;

当您在源文件中包含 game.h 时,globalGameObj 名称变得可见。您还需要创建一个实际对象。在源文件中,例如 game.cc(在任何类之外):

Game globalGameObj;

通过变量名访问它:

globalGameObj.do_some_work();

选项 2

使用通常称为单例的模式。将以下内容添加到您的游戏类 (game.h) 中:

class Game
{
  public:
    static Game &shared_instance() {static Game game; return game;}

  private:
    // Make constructor private. Only shared_instance() method will create an instance.
    Game() {/*whatever initialisation you need*/}
};

您可以使用 shared_instance() 方法访问 Game 实例:

Game::shared_instance().do_some_work();

你不使用static class PublicInstances上面的任何东西。C++ 允许您引入一个命名空间(例如 PublicInstances)来提供名称隔离并将您的全局对象保存在一个地方,但这可能是一种矫枉过正。无论如何,如果您的全局对象很少,那么它可能是一个糟糕的设计。

什么选择更好?有些人会争辩说应该使用单例模式。它保证只创建一个实例。但是,选项 1 和选项 2 都有相同的问题:它们在代码中引入了一个全局对象,而所有缺点都归因于全局变量。我会说单例是变相的全局对象。我不认为有利于这两种选择的决定技术原因,所以我会说这是个人品味的问题。

历史注释:)

我对选项 2 的第一个建议是使用动态分配的 Game 对象而不是函数本地静态对象。

static Game *instance() {if (!_inst) _inst = new Game(); return _inst;}

很少有人认为这不再是最好的方法了,谢谢KalargiopewebSimple。C++03 在存在线程的情况下初始化静态对象存在问题。C++11 保证静态的安全初始化。

C++11 草案,第 6.7 节

这样的变量在控制第一次通过其声明时被初始化;这样的变量在其初始化完成时被认为已初始化。[...]如果在初始化变量时控制同时进入声明,则并发执行应等待初始化完成。

于 2013-10-02T04:39:45.997 回答