ava*_*obo 5 c# c++ static class global-variables
几个月前,我创建了一个名为Vexed的游戏C#项目.现在我正在创建一个俄罗斯方块,但在C++中.基本上我想使用我在其他项目中使用的相同逻辑,它有点像这样:
我创建了一个名为"游戏"的类,其中包含有关游戏的所有信息.它有它的方法,变量和一切.然后,我创建了一个名为"PublicInstances"的静态类或者类似的东西,在那个类中我声明了这样的东西:
static class PublicInstances
{
public static Game vexedGame = new Game(); //This is C# and works.
}
Run Code Online (Sandbox Code Playgroud)
这使得它的使用变得如此简单,因为我在游戏中所做的任何更改都保存在我的类的静态实例中,我可以在项目的任何地方访问它.我想知道如何用C++做到这一点,创建我的类Game的公共或全局实例,这样我就可以访问它并在任何地方更改它,并在我的项目的任何Form或类中更新所有内容.我将衷心感谢您的帮助.
//对不起,如果我的英语不是最好的^^
重新审视和总结
选项1
您可以简单地声明和定义Game对象的全局实例.在头文件中,例如game.h:
extern Game globalGameObj;
Run Code Online (Sandbox Code Playgroud)
当您在源文件中包含game.h时,globalGameObj名称将变为可见.您还需要创建一个实际对象.在源文件中,例如game.cc(在任何类之外):
Game globalGameObj;
Run Code Online (Sandbox Code Playgroud)
通过变量名访问它:
globalGameObj.do_some_work();
Run Code Online (Sandbox Code Playgroud)
选项2
使用通常称为单身的模式.将以下内容添加到您的Game类(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*/}
};
Run Code Online (Sandbox Code Playgroud)
您可以使用shared_instance()方法访问Game实例:
Game::shared_instance().go_some_work();
Run Code Online (Sandbox Code Playgroud)
你不使用static class PublicInstances上面的任何东西.C++允许您引入一个名称空间(例如PublicInstances)来提供名称隔离并将您的全局对象保存在一个地方,但它可能是一个过度杀伤.在任何情况下,如果你有很少的全局对象,那么它可能是一个糟糕的设计.
什么选择更好?有些人会争辩说应该使用单身人士模式.它保证只创建一个实例.但是,选项1和选项2都有相同的问题:它们在代码中引入了一个全局对象,所有缺点都归因于全局变量.我会说单身人士是伪装的全球对象.我认为决定技术原因并不支持任何一种选择,所以我认为这是个人品味的问题.
历史记录:)
我对选项2的第一个建议是使用动态分配的Game对象而不是函数本地静态对象.
static Game *instance() {if (!_inst) _inst = new Game(); return _inst;}
Run Code Online (Sandbox Code Playgroud)
很少有人认为这不是最好的方式,谢谢Kal,argiopeweb和Simple.C++ 03在存在线程时初始化静态对象存在问题.C++ 11保证静态初始化静态.
C++ 11 draft,secion 6.7
such a variable is initialized the first time control passes through its declaration;
such a variable is considered initialized upon the completion of its initialization. [...]
If control enters the declaration concurrently while the variable is being initialized,
the concurrent execution shall wait for completion of the initialization.
Run Code Online (Sandbox Code Playgroud)