Clase singleton de C++ haciendo el constructor privado.
Intenté usar el patrón de diseño singleton haciendo que la clase sea prácticamente única mediante la creación de un constructor no público. Sin embargo, cuando lo probé, el resultado no fue el esperado. Si se crea solo una instancia, el valor debería ser el mismo para las referencias, pero aparentemente son diferentes como se muestra a continuación. ¿Qué está mal con el código?
Código:
class SortOfSingleton
{
public:
static SortOfSingleton& getInstance();
int value = 0;
private:
SortOfSingleton(int value);
};
SortOfSingleton::SortOfSingleton(int value)
{
std::cout << "Creando nueva instancia." << std::endl;
this->value = value;
}
SortOfSingleton& SortOfSingleton::getInstance()
{
static SortOfSingleton instance(5);
return instance;
}
void main()
{
auto instance1 = SortOfSingleton::getInstance();
instance1.value = 100;
std::cout << instance1.value << std::endl;
auto instance2 = SortOfSingleton::getInstance();
std::cout << instance2.value << std::endl;
}
Resultado real:
Creando nueva instancia.
100
5
Resultado esperado:
Creando nueva instancia.
100
100
davy.ai
El problema con el código es que el constructor todavía es accesible a través del método
getInstance()
, lo que significa que se pueden crear múltiples instancias, lo que va en contra de la intención del patrón singleton. Para hacer cumplir por completo el patrón singleton, el constructor debería ser privado ygetInstance()
debería ser la única forma de crear la instancia. En el código proporcionado, el constructor está marcado como privado, pero aún es accesible a través de la declaración de instancia estática en el métodogetInstance()
.Para solucionar este problema, deberíamos eliminar el parámetro del constructor y pasar el
value
como un parámetro separado al métodogetInstance()
. Esto asegurará que solo haya una instancia de la clase y que elvalue
siempre sea el mismo para esa instancia. Aquí hay un fragmento de código actualizado:En este código actualizado, el método
getInstance()
toma el parámetrovalue
y lo pasa al constructor privado. El constructor inicializa la variable miembrom_value
y el métodogetValue()
la devuelve. El métodogetInstance()
siempre devuelve la misma instancia ya que se declara como una variable estática. Ahora, la salida será:En resumen, solo hay una instancia de la clase y el
value
es el mismo para ambas referencias.