我正在尝试编写多线程游戏结构。我下面的是基本结构。 EventManager、LogicManager、Renderer都是线程。他们从一个通用的 Gamestate 类读取/写入,该类将处理线程之间的所有共享资源。据我了解,Gamestate 在技术上应该是一个 Singleton。那是对的吗?我还想知道如何将其实现为“早期初始化单例”,如下所述:http://www.oodesign.com/singleton-pattern.html#early-singleton ,除了在 C++ 中。恐怕我不太精通 C++ 静态,因此我不知道将“private static Singleton instance = new Singleton();”放在哪里C++ 中的行。我知道我可以通过解决方法获得相同的效果,但我想尝试这种方式。
int main(){
Gamestate gs;
EventManager em(&gs);
LogicManager lm(&gs);
Renderer renderer(&gs);
lm.start();
renderer.start();
em.eventLoop();
return 0;
}
最佳答案
正如@juanchopanza 和@Dietmar 评论的那样,游戏状态真的没有理由应该是单例。
此外,我能想到为什么它不应该是一个的几个原因:
单例使得单元测试变得非常困难。模拟单例比模拟接口(interface)要困难得多。
假设有一天您想要扩展您的游戏?例如,如果有一天您想让游戏逻辑在服务器上运行并让您的玩家运行客户端(想想多人游戏)怎么办?在这种情况下,您可能希望在您的流程中拥有多个游戏状态,而单例会不必要地限制您。
如果您想对游戏状态做一些事情,例如将其序列化以在机器之间发送,或者可能从文件中保存和加载它,将游戏状态设为单例会使它变得更加困难。使用标准序列化框架变得很麻烦。
很难将依赖项注入(inject)到单例中。如果您需要一些组件或数据来初始化您的游戏状态怎么办?在这种情况下,您将有一段时间内某些线程可能会访问游戏状态实例,即使它处于不一致状态也是如此。
我可能会想到更多的原因。无论如何,我的建议是为所有组件定义接口(interface),并让每个组件接收它所依赖的组件作为构造函数参数的接口(interface)。
这使得编写解耦良好的类、防止类膨胀和进行良好的单元测试变得更加容易。
然后您可以使用任何反转控制框架自动神奇地将游戏初始化代码中的所有组件绑定(bind)在一起。
关于c++ - 正确使用和实现单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13758677/