una resueltos resolucion programacion orientada operador objetos miembros ejercicios ejemplos codigo clases clase ambito c++ singleton

resueltos - operador de resolucion de ambito c++



Instancia global de una clase en C++ (7)

Como dice el título. ¿Cómo crearía una instancia de una clase que esté disponible globalmente (por ejemplo, tengo un functor para imprimir y quiero tener una única instancia global de esto (aunque la posibilidad de crear más)).


Como una ligera modificación del patrón singleton, si también desea permitir la posibilidad de crear más instancias con distintas duraciones, simplemente haga que ctors, dtor y operator = public sean públicos. De esta forma, obtienes la única instancia global a través de GetInstance, pero también puedes declarar otras variables en el montón o la pila del mismo tipo.

La idea básica es el patrón singleton, sin embargo.


En primer lugar, el hecho de que desee variables globales es un "olor a código" (como Per Martin Fowler).

Pero para lograr el efecto deseado, puede usar una variación del Singleton.
Use variables de funciones estáticas. Esto significa que la variable no se crea hasta que se use (esto le da una evaluación perezosa) y todas las variables se destruirán en el orden inverso de creación (por lo que esto garantiza que se usará el destructor).

class MyVar { public: static MyVar& getGlobal1() { static MyVar global1; return global1; } static MyVar& getGlobal2() { static MyVar global2; return global2; } // .. etc }


Hacer todo el esfuerzo de hacer que un objeto singleton use el patrón habitual no aborda la segunda parte de su pregunta, la capacidad de hacer más si es necesario. El "patrón" singleton es muy restrictivo y no es más que una variable global con otro nombre.

// myclass.h class MyClass { public: MyClass(); void foo(); // ... }; extern MyClass g_MyClassInstance; // myclass.cpp MyClass g_MyClassInstance; MyClass::MyClass() { // ... }

Ahora, en cualquier otro módulo solo incluya myclass.h y use g_MyClassInstance como de costumbre. Si necesita hacer más, hay un constructor listo para llamar.


La implementación más sencilla y concurrente es el singleton de Scott Meyer:

#include <iostream> class MySingleton { public: static MySingleton& Instance() { static MySingleton singleton; return singleton; } void HelloWorld() { std::cout << "Hello World!/n"; } }; int main() { MySingleton::Instance().HelloWorld(); }

Ver el tema IV aquí para un análisis de John Vlissides (de fama GoF).


Prefiero permitir un singleton pero no aplicarlo así que nunca escondas los constructores y los destructores. Eso ya se había dicho solo dando mi apoyo.

Mi giro es que no uso a menudo el uso de una función miembro estática a menos que quiera crear un singleton verdadero y ocultar el constr. Mi enfoque habitual es este:

template< typename T > T& singleton( void ) { static char buffer[sizeof(T)]; static T* single = new(buffer)T; return *single; } Foo& instance = singleton<Foo>();

¿Por qué no usar una instancia estática de T en lugar de una ubicación nueva? La instancia estática le da a la orden de construcción garantías, pero no orden de destrucción. La mayoría de los objetos se destruyen en orden inverso de construcción, pero variables estáticas y globales. Si usa la versión estática de la instancia, eventualmente obtendrá segfaults misteriosos / intermitentes, etc. después del final de main.

Esto significa que nunca se llamará al destructor singletons. Sin embargo, el proceso para bajar de todos modos y los recursos serán reclamados. Es algo difícil de acostumbrar, pero créeme que no hay una mejor solución de plataforma cruzada en este momento. Afortunadamente, C ++ 0x ha realizado cambios para garantizar el orden de destrucción que solucionará este problema. Una vez que el compilador admite el nuevo estándar, simplemente actualice la función singleton para usar una instancia estática.

Además, en la implementación real uso boost para obtener memoria alineada en lugar de una matriz de caracteres simples, pero no quería complicar el ejemplo