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)).instancia global de una clase en C++
Respuesta
Hacer todo el esfuerzo de hacer que un objeto singleton utilizando el patrón habitual no aborde la segunda parte de su pregunta, la posibilidad 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 basta con incluir myclass.h
y utilizar g_MyClassInstance
como de costumbre. Si necesita hacer más, hay un constructor listo para llamar.
Ugh. Esto se romperá si MyClass depende de alguna otra instancia global que se inicialice primero, ya que el orden de inicialización de los globales es "aleatorio". Es mejor usar clase de fábrica de clase regular + (crear una sola instancia). – richq
@rq: No es aleatorio: vea http://stackoverflow.com/questions/294270/how-do-you-call-a-constructor-for-global-objects-for-arrays-of-objects-and-for # 294308 –
Aleatorio, indefinido, no se puede determinar en tiempo de compilación ... misma diferencia. – richq
Singleton pattern es lo que estás buscando.
Como una ligera modificación en el 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.
La implementación más sencilla y segura de concurrencia es 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 tema IV here para un análisis de John Vlissides (de la fama GoF).
NO ES concurrencia segura. En C++ estándar, la estática se "inicializa" cuando el constructor finaliza, por lo que cada hilo que ingrese al método Instance() en el momento de la inicialización causará la recreación del singleton, –
Dmitry Khalatov @ Técnicamente correcto. Hay varias soluciones simples. a) Use gcc tiene una solución explícita para tratar esto (no estándar). b) Cree el objeto antes de cualquier subproceso c) Use un candado dentro del método Instance(). –
Estoy de acuerdo con @Dmitry: hasta que el estándar proporcione una forma de manejar la presencia de hilos, no es seguro. – xtofl
Singleton es un buen patrón para usar, pero tiene sus propias desventajas. Lea los siguientes blogs de Miško Hevery antes de usar singletons.
En primer lugar el hecho de que desea variables globales es un 'olor código' (como por Martin Fowler).
Pero para lograr el efecto que desee puede usar una variación del Singleton.
Usar 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
}
De acuerdo con esta lógica, std :: cout también es un olor a código. –
@ rr-: Debería leer [libro de "Fowlers de Martin" sobre refactorización] (http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=sr_1_1?ie=UTF8&qid= 1439219908 & sr = 8-1 & keywords = refactoring + by + martin + fowler). –
@ rr-: O cualquiera de los millones de artículos sobre [El estado mutable global es malo] (http://programmers.stackexchange.com/questions/148108/why-is-global-state-so-evil) –
Prefiero permitir un singleton pero no aplicarlo así que en nunca ocultar los constructores y destructores. Eso ya se había dicho solo dando mi apoyo.
Mi error es que no uso a menudo el uso de una función de miembro estático 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 utilizar 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.
También, en el implemenation real utilizo impulso para conseguir la memoria alineados en lugar de una matriz de caracteres sin formato, pero no quería complicar el ejemplo
- 1. Uso de singleton en lugar de una instancia global estática
- 2. Crear una instancia de una clase python en C#
- 3. ¿Cómo crea C# una instancia de una clase?
- 4. Creando una instancia de una clase con()
- 5. Confuso: creación de instancia de la clase C# en C++
- 6. ¿Se puede reemplazar una instancia de una clase en JavaScript?
- 7. V8 FunctionTemplate Clase Instancia
- 8. ¿Cómo puedo crear una nueva instancia de clase de una clase dentro de una clase (estática)?
- 9. declarar una instancia de una clase const
- 10. Declarar una instancia de una clase dentro de esa clase
- 11. C#: probar si una clase en una instancia de una súper clase en lugar de una subclase
- 12. C#: Creando una instancia de una clase abstracta sin definir la nueva clase
- 13. Miembros estáticos de una clase de instancia
- 14. C++ miembro de la clase puntero a la función global
- 15. C/C++ ¿Es posible obtener una "lista" de miembros de instancia al consultar una clase?
- 16. Inicializando una estructura global en C
- 17. Creación de una instancia de una clase anidada en XAML
- 18. Método de clase global vs función vs clase estática
- 19. Creando una instancia de la clase interna
- 20. Creación de una instancia de una clase C++ y métodos de llamada sobre ella en Python
- 21. ¿cómo podría crear una clase de notificación global?
- 22. ¿Puede una instancia de clase autodestruirse?
- 23. cómo crear dinámicamente una instancia de una clase en python?
- 24. Agregando una variable de instancia a una clase en Ruby
- 25. ¿Invocar un método de clase C++ sin una instancia de clase?
- 26. Cómo crear una instancia de una clase en Objective-C que no heredan de NSObject
- 27. ¿Qué sucede en la memoria cuando se crea una instancia de una clase de C++?
- 28. ¿Cómo declarar una variable global desde dentro de una clase?
- 29. ¿Cómo declarar una instancia de clase como una constante en C#?
- 30. Cómo crear una instancia dinámica de una clase en Objective-C
Esta pregunta anterior es sólo un ejemplo de un producto único aquí en StackOverflow: http://stackoverflow.com/questions/270947/can-any-one-provide-me-a-sample-of-singleton-in-c –