我应该使用全局变量吗?

Gas*_*sim 11 c++ singleton global g++

我一直在阅读关于全局变量以及它们有多糟糕但我因此而被困在一个地方.我将非常具体地说明在这种情况下我是否应该使用全局变量.

我正在研究游戏引擎.我的引擎由很多经理组成.管理人员执行某些任务 - 他们存储资源,加载资源,更新资源等.

我让所有的经理都成了一个单身人士,因为很多类和函数需要访问它们.我正在考虑删除单身人士,但我不知道我怎么也不能拥有它并获得这些经理的访问权限.

这是我想说的一个例子(我的英文不好,对不起):

Singleton.h

template<class T> class Singleton {
private:
    Singleton( const Singleton& );
    const Singleton& operator=( const Singleton& );

protected:
    Singleton() { instance = static_cast<T*>(this); }
    virtual ~Singleton() {}

protected:
    static T * instance;

public:
    static T &Instance() {
        return *instance;
    }

};
Run Code Online (Sandbox Code Playgroud)

ScriptManager.h

class ScriptManager : public Singleton<ScriptManager> {
public:
    virtual void runLine(const String &line)=0;
    virtual void runFile(const String &file)=0;
};
Run Code Online (Sandbox Code Playgroud)

PythonScriptManager.cpp

class PythonScriptManager : public ScriptManager {
public:
    PythonScriptManager() { Py_Initialize(); }
    ~PythonScriptManager() { Py_Finalize(); }

    void runFile(const String &file) {
        FILE * fp = fopen(file.c_str(), "r");
        PyRun_SimpleFile(fp, file.c_str());
        fclose(fp);
        fp=0;
    }

    void runLine(const String &line) {
        PyRun_SimpleString(line.c_str());   
    }

};
Run Code Online (Sandbox Code Playgroud)

实体ScriptComponent

#include <CoreIncludes.h>
#include <ScriptManager.h>
#include <ScriptComponent.h>

void update() {

    ScriptManager::Instance().runFile("test_script.script");
    //i know its not a good idea to open the stream on every frame but thats not the main concern right now.
}
Run Code Online (Sandbox Code Playgroud)

应用

int main(int argc, const char * argv) {
    Application * app = new Application(argc, argv);
    ScriptManager * script_manager = new PythonScriptManager;
    //all other managers

    return app->run();
}
Run Code Online (Sandbox Code Playgroud)

如你所见,我甚至没有在我的ScriptComponent.cpp文件中包含上面的文件,这使我获得了一些编译时间.如何在没有全局变量的情况下获得那种结果,这样可以很容易地集成到这个结果中.单例不是线程安全的,但添加线程不会花费很长时间.

我希望我能解释一下这个问题.

提前谢谢,
Gasim Gasimzada

jal*_*alf 26

我不会说你永远不应该使用全局变量,但是:

  • 永远不要使用单身人士.就是原因.它们太可怕了,而且它们比普通的老式全球性要糟糕得多.
  • "经理"课很糟糕.他们"管理"了什么?他们如何"管理"它?"经理"课程需要分解为您可以描述的内容.一旦弄清楚"管理"对象意味着什么,就可以定义一个或多个具有更明确职责的对象.
  • 当你使用全局变量时,不要让它们变得可变.只写全局是可以接受的(考虑一个记录器.你写它,但它的状态永远不会影响应用程序),只读全局变量也可以(考虑从不改变的各种常量,但你经常需要阅读).全局变为有害的地方是当它们具有可变状态时:当你同时阅读和写出它们时.

最后,非常简单的替代方案:将依赖关系作为参数传递.如果一个对象需要某些东西才能运行,那么在它的构造函数中传递"something".如果函数需要某些东西才能运行,那么将"某事"作为参数传递给它.

这可能听起来像很多工作,但事实并非如此.当你的设计混杂着全球和单身时,你会得到一个巨大的意大利面条建筑,其中一切都取决于其他一切.因为依赖关系不是明确可见的,所以你得到了草率,而不是考虑连接两个组件的最佳方法是什么,你只需要通过一个或多个全局变量进行通信.一旦你必须考虑明确传递哪些依赖关系,大多数依赖关系都是不必要的,并且你的设计变得更清晰,更易读和可维护,并且更容易推理.并且您的依赖项数量将急剧下降,因此您实际上只需要将额外的参数或两个参数传递给少量对象或函数.