重新审视和总结
选项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;}
很少有人认为这不再是最好的方法了,谢谢Kal、argiopeweb和Simple。C++03 在存在线程的情况下初始化静态对象存在问题。C++11 保证静态的安全初始化。
C++11 草案,第 6.7 节
这样的变量在控制第一次通过其声明时被初始化;这样的变量在其初始化完成时被认为已初始化。[...]如果在初始化变量时控制同时进入声明,则并发执行应等待初始化完成。