Cómo crear un singleton en C++

Como Crear Un Singleton En C



En C++, un singleton es un principio de diseño que garantiza la presencia de una instancia solitaria de la clase en todo el programa y proporciona un punto de acceso global a esa instancia en particular.

El patrón singleton se usa comúnmente cuando necesita tener un único recurso compartido al que se debe acceder globalmente, como una conexión de base de datos, un registrador o un administrador de configuración. Al imponer una única instancia, permite que varias partes del programa accedan y modifiquen el mismo objeto, promoviendo la coherencia de los datos y reduciendo la necesidad de variables globales. Singleton se puede emplear como caché de objetos donde los objetos utilizados con frecuencia o de creación costosa se almacenan y reutilizan en toda la aplicación. Este enfoque ayuda a mejorar el rendimiento al evitar la creación e inicialización de objetos redundantes.

En este artículo, explicaremos la creación de un singleton y demostraremos un ejemplo de cómo estilizar un singleton en un programa C++.







Ejemplo 1: creación de un singleton simple con inicialización ansiosa

Un singleton simple con inicialización temprana es un patrón de diseño que garantiza que solo se cree una instancia de una clase y se crea con entusiasmo durante la inicialización estática.



Demostraremos el fragmento de código básico para la creación de un singleton simple con inicialización ansiosa. Empecemos con el programa:



#incluir

clase singleton {
privado :
  estático único * instancia ;
único ( ) { }
público :
  estático único * obtener Instancia ( ) {
    devolver instancia ;
  }
} ;


único * único :: instancia = nuevo singleton ( ) ;

En t principal ( ) {

único * instancia1 singleton = único :: obtener Instancia ( ) ;

único * instancia singleton2 = único :: obtener Instancia ( ) ;

enfermedad de transmisión sexual :: corte << 'singletonletonInstance1: ' << instancia1 singleton << enfermedad de transmisión sexual :: fin ;

enfermedad de transmisión sexual :: corte << 'singletonletonInstance2: ' << instancia singleton2 << enfermedad de transmisión sexual :: fin ;

  devolver 0 ;

}

El código incluye el encabezado que proporciona la funcionalidad para trabajar con flujos de entrada y salida como 'std::cout'.





Después de incluir el archivo de encabezado, definimos la clase 'Singleton' que representa la implementación del patrón singleton. Tiene un constructor privado y una variable miembro estática privada llamada 'instancia'.

Luego, la función getInstance() se implementa como una función miembro estática pública de la clase 'Singleton'. Devuelve la instancia del singleton que se almacena en la instancia de la variable miembro estática. La instancia de la variable miembro estática se define e inicializa fuera de la clase con “Singleton* Singleton::instance = new Singleton();”. Esta línea inicializa con entusiasmo la instancia de la clase 'Singleton' durante la inicialización estática.



En la función main(), declaramos dos punteros, 'singletonInstance1' y 'singletonInstance2', y asignamos el valor que se devuelve llamando a Singleton::getInstance(). Dado que la instancia se inicializa con entusiasmo, ambos punteros apuntan a la misma instancia. Las declaraciones 'std::cout' imprimen las direcciones de memoria de 'singletonInstance1' y 'singletonInstance2' en la consola usando el operador '<<' y 'std::endl'.

El código termina con un 'retorno 0' que indica una ejecución exitosa del programa.

Cuando ejecuta este código, el resultado es algo como esto:

El resultado muestra las direcciones de memoria de 'singletonInstance1' y 'singletonInstance2'. Dado que a ambos punteros se les asigna la misma instancia que se obtiene de Singleton::getInstance(), tienen la misma dirección de memoria. Esto demuestra cómo el patrón singleton garantiza que haya una única instancia de la clase y que las llamadas futuras a getInstance() siempre resulten en la misma instancia.

Ejemplo 2: Implementación de patrón Singleton con inicialización diferida

Esta demostración explica la implementación del patrón singleton con inicialización diferida y muestra su uso en la función main(). La explicación paso a paso del fragmento de código se proporciona después de este programa:

#incluir

clase singleton {

privado :

  estático único * instancia ;

único ( ) {

enfermedad de transmisión sexual :: corte << 'Se creó una instancia singleton'. << enfermedad de transmisión sexual :: fin ;

  }

público :

  estático único * obtener Instancia ( ) {

    si ( instancia == nulo ) {

instancia = nuevo singleton ( ) ;

    }

    devolver instancia ;

    }

    vacío Mostrar mensaje ( ) {

enfermedad de transmisión sexual :: corte << '¡Hola desde Singleton!' << enfermedad de transmisión sexual :: fin ;

    }

~ Singleton ( ) {

enfermedad de transmisión sexual :: corte << 'Instancia Singleton destruida'. << enfermedad de transmisión sexual :: fin ;

    }

    } ;

único * único :: instancia = nulo ;

    En t principal ( ) {

único * instancia1 singleton = único :: obtener Instancia ( ) ;

instancia1 singleton -> Mostrar mensaje ( ) ;

único * instancia singleton2 = único :: obtener Instancia ( ) ;

instancia singleton2 -> Mostrar mensaje ( ) ;

      devolver 0 ;

}

El programa comienza agregando el archivo de encabezado para realizar las tareas de entrada/salida. Luego, declaramos y definimos una clase 'Singleton'. La única instancia de la clase se mantiene dentro de la variable miembro estática privada denominada 'instancia'.

Cada vez que se llama al constructor de la clase 'Singleton', genera una instancia de la clase 'Singleton'. Envía el mensaje 'Instancia Singleton creada' a la consola usando 'std::cout << … << std::endl;'. El constructor no tiene ningún parámetro ya que es un constructor predeterminado. Se define como Singleton() sin ningún argumento. Lo declaramos privado, lo que significa que sólo se puede invocar desde dentro de la clase. Esto evita una instanciación directa de la clase 'Singleton' y garantiza que la única forma de obtener una instancia sea a través de la función getInstance().

El método getInstance() de la clase 'Singleton' se declara como una función miembro estática pública. Tiene la función de establecer y otorgar accesibilidad a la instancia singleton. Dentro de getInstance(), comprueba si la instancia es 'nullptr'. Si es así, lo que significa que la instancia aún no está presente, utiliza el constructor privado para crear una instancia de un nuevo objeto de la clase 'Singleton'.

La función showMessage() es una función miembro simple que muestra el mensaje '¡Hola desde Singleton!' mensaje. El destructor de singleton está definido. Se llama implícitamente cuando el programa finaliza e imprime la 'instancia Singleton destruida'. mensaje que indica que la instancia singleton está destruida. La instancia de la variable miembro estática se define inicialmente como 'nullptr'.

El int main() inicia la definición de la función main(). Luego, “Singleton* singletonInstance1 = Singleton::getInstance();” llama a la función getInstance() de la clase 'Singleton' para obtener un puntero a la instancia singleton. Asigna este puntero a la variable 'singletonInstance1'.

Después de eso, 'singletonInstance1->showMessage();' utiliza el operador de flecha (->) para llamar a la función showMessage() en el puntero 'singletonInstance1'. Esta función muestra el mensaje que se especifica en ella en la consola. Luego, “Singleton* singletonInstance2 = Singleton::getInstance();” llama a la función getInstance() nuevamente, obteniendo otro puntero a la instancia singleton. Esta vez, asigna el puntero a la variable 'singletonInstance2'. El 'singletonInstance2->showMessage();' llama a la función showMessage() en el puntero 'singletonInstance2'. Esta función muestra el mensaje '¡Hola desde Singleton!' mensaje nuevamente a la consola.

Por último, 'devuelve 0'; significa el final de la función main() y el programa devuelve el valor 0, lo que significa una ejecución exitosa del programa.

Aquí está el resultado del fragmento de código explicado anteriormente:

Este resultado confirma que la clase 'Singleton' asegura la creación de una sola instancia y que llamadas posteriores a la función getInstance() producen de manera confiable la misma instancia.

Conclusión

Crear un singleton en C++ es un concepto muy útil. En esta publicación, cubrimos inicialmente la sección de introducción de singleton. Además, se producen dos ejemplos para implementar el singleton en C++. La primera ilustración muestra la implementación de la inicialización singleton ansiosa. Mientras que la implementación de inicialización diferida del patrón singleton se proporciona en el segundo ejemplo de este artículo. Además, las instantáneas del resultado producido también se muestran para los programas correspondientes.