He estado leyendo acerca de las variables globales y lo malas que son, pero estoy atrapado en un lugar debido a eso. Voy a ser muy específico acerca de si debería usar variables globales en este escenario.¿Debo usar variables globales?
Estoy trabajando en un motor de juegos. Y mi motor se compone de muchos gerentes. Los administradores realizan ciertas tareas: almacenan recursos, los cargan, los actualizan, etc.
He convertido a todos mis administradores en singleton porque hay tantas clases y funciones que necesitan acceso a ellos. Estaba pensando en eliminar el singleton pero no sé cómo no puedo tenerlo y obtener acceso a estos gerentes.
Aquí es un ejemplo de lo que estoy tratando de decir (im malo en Inglés, lo siento):
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;
}
};
ScriptManager.h
class ScriptManager : public Singleton<ScriptManager> {
public:
virtual void runLine(const String &line)=0;
virtual void runFile(const String &file)=0;
};
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());
}
};
Entidad 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.
}
Aplicación
int main(int argc, const char * argv) {
Application * app = new Application(argc, argv);
ScriptManager * script_manager = new PythonScriptManager;
//all other managers
return app->run();
}
Como se puede ver que ni siquiera estoy incluyendo los archivos anteriores en mi archivo ScriptComponent.cpp que me gana un poco de tiempo de compilación. ¿Cómo puedo obtener ese tipo de resultado sin globales que hará que sea fácil de integrar como este. El singleton no es seguro para subprocesos, pero agregar hilos no llevará mucho tiempo.
Espero haber podido explicar el problema.
Gracias de antemano,
Gasim Gasimzada
No hay misterio. La forma de evitar los globales es no tenerlos. Si la función A necesita acceder al objeto B, y B no es global, entonces B no ha pasado como argumento a A. Y así es como lo haces si no tienes valores globales. Pase los objetos necesarios como argumentos de función (o constructor). – jalf
Como no puedo comentar sobre sus publicaciones, voy a comentar aquí. @jalf realmente entiendo que los globales son malos y una solución alternativa y robusta es pasar los valores a los argumentos de funciones o c'tors. ¿Pero tengo dos grandes problemas en ese caso? ¿De dónde estoy obteniendo esos gerentes (en realidad son solo envoltorios para facilitar la codificación)? @Dave dijo que el objeto 'ejecutivo' (vamos a llamarlo Engine) que almacena todos estos objetos y pasa las referencias a la función o c'tor. ¿Pero cómo lo estoy haciendo? Quiero que sea más fácil y más limpio. – Gasim
En realidad, no importa. He encontrado una manera :) La única razón por la que quería usar singletons es porque tendré que tener muy poca dependencia en cada archivo fuente, pero ahora he encontrado una manera :) ¡Gracias chicos por toda su ayuda! Ahora volviendo al trabajo. – Gasim