Historia de la pregunta:
El patrón Singleton fue propuesto para limitar la creación de solo una instancia de una clase determinada, lo cual era necesario para implementar administradores globales (por ejemplo, registradores, grupos de recursos, configuradores).
Problema:
La implementación del Singleton parece simple, pero en C++ surgen dificultades: seguridad en hilos, corrección de la destrucción, orden de inicialización.
Solución:
La forma más segura y moderna de implementar Singleton utiliza una variable local estática dentro de una función estática, lo que garantiza la inicialización en la primera llamada, seguridad en hilos (a partir de C++11) y destrucción correcta.
Ejemplo de código:
class Singleton { public: static Singleton& instance() { static Singleton s; return s; } void doSomething() {} private: Singleton() {} Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; };
Características clave:
¿Se puede crear una segunda instancia de Singleton mediante serialización o clonación?
Sí. Si se implementan métodos de serialización/deserialización o se implementa manualmente clone(), sin restringir el constructor de copia, puede aparecer una segunda instancia. Para evitar esto, se requiere prohibir todos los métodos de copia, clonación y recuperación a través de la serialización.
¿Se implementará correctamente el Singleton en un entorno multihilo en C++98/03 estándar a través de una variable estática local?
No. Las variables estáticas locales antes de C++11 no garantizaban la seguridad en hilos durante la inicialización. Esto podría resultar en la creación de múltiples instancias si dos hilos entraban simultáneamente en la función instance(). En C++11 y versiones posteriores, el problema se resolvió a nivel de estándar.
¿Cuándo se destruye la instancia de Singleton creada a través de una variable local estática?
El objeto se destruye en orden inverso al de su creación (LIFO) en la etapa de finalización del programa (exit). Pero esto puede llevar a problemas si el destructor accede a objetos que ya han sido destruidos.
En un sistema de registro, el desarrollador implementa el Singleton con un puntero global y new, olvidando prohibir la copia. El programa funciona, pero en un entorno multihilo a veces se obtienen diferentes instancias del registrador, y los mensajes se pierden.
Ventajas:
Desventajas:
Singleton se implementa a través de una variable local estática en una función estática, se prohíbe la copia. La seguridad en hilos está garantizada, el programa escala, y los registros se separan correctamente.
Ventajas:
Desventajas: