2011-07-12 6 views
5

¿Alguien puede justificar la necesidad de privatizar el operador de asignación en una implementación de clase Singleton?Necesidad de privatizar el operador de asignación en una clase Singleton

¿Qué problema soluciona al hacer Singleton& operator=(Singleton const&); privado?

class Singleton { 
public: 
    static Singleton& Instance() { 
    static Singleton theSingleton; 
    return theSingleton; 
    } 

private: 
    Singleton(); // ctor hidden 
    Singleton(Singleton const&); // copy ctor hidden 
    Singleton& operator=(Singleton const&); // assign op. hidden 
    ~Singleton(); // dtor hidden 
}; 

Respuesta

10

Asignación de un conjunto unitario es simplemente una operación sin sentido, ya que sólo un objeto de lo que nunca debería existir.

Hacer que el operador de asignación privada facilita el diagnóstico de código sin sentido como las siguientes:

Singleton& a = Singleton::Instance(); 
Singleton& b = Singleton::Instance(); 
a = b; // Oops, accidental assignment. 
+2

Entiendo incluso si un desarrollador hace a = b; no hay daño ya que ambos objetos apuntan a la misma instancia estática de Singleton. Entonces, el operador de privatización o asignación no es obligatorio para que un singleton se comporte como se espera. –

+1

@PrashanthGN Es correcto que esto no sea una operación, por lo que tener 'operator =' no es peligroso, solo tonterías. –

2

Solo hay un singleton. No tiene sentido copiarlo. Necesita dos cosas para que una copia sea sensata y la mayoría de los operadores de copia deben verificar self==&other para estar seguros.

Este truco de private es un truco. C++0x does it better.

Begin diatriba ...

mi humilde opinión un Singleton es una contradicción en los términos. Es un producto de la idea tonta de que todo debe ser un objeto para ser encapsulado. Es el mismo brainache que llevaba el Math.sin(x) de Java y otros.

Su vida será más simple si el "singleton" es simplemente un conjunto de funciones gratuitas en un espacio de nombres. Cualquier "miembro" privado del singleton puede ocultarse en un espacio de nombre anónimo en .cpp. Encapsulación lograda, y no tienes esa complicada sintaxis adicional.

MyNamespace :: foo(); 

en lugar de

MyClass :: instance() .foo(); 
+0

Sin embargo, el operador de asignación no se usa realmente para copiar. –

+0

Pero llama al constructor. – 3nixios

+0

Las funciones en 'MyNamespace' pueden necesitar compartir el estado, que luego se encapsularía en un objeto del que existe exactamente un objeto. Y de vuelta es el singleton. Es * rara * útil, pero a veces * es * realmente útil. Por supuesto, no es necesario adherirse a este patrón particular de 'Singleton' de una clase, el estado también puede ser administrado por una función especial que devuelve un local estático. Pero esto es solo una diferencia sintáctica. –

0

Cuando se utiliza un producto único de la razón a ponerla en práctica se debe a que sólo desea una instancia de un objeto de esa clase. En otras palabras, no es necesario hacer una copia de la instancia porque solo puede tener una instancia. Es lo mismo para el constructor de copia.

2

Si solo desea una instancia, el constructor de copia debe ser privado. El especificador de acceso al operador de asignación no importa, porque de todos modos será imposible de usar.

0

Mi razonamiento es este: si solo una instancia puede estar presente, el operador = podría definirse sin problema, ya que no hará nada significativo. si lo hacemos de forma privada, el compilador agregará un nivel más de seguridad al marcar cualquier intento de usar ese operador como un error.

El mismo razonamiento vale para el destructor, por cierto.

1

Convertir el operador de asignación en privado realmente no cambia nada, ya que necesita dos instancias para poder asignar. Corresponde a con lo que las personas pueden esperar ver; es habitual que si el constructor de copia es privado, el operador de asignación también lo es. Declarar un operador de asignación privada simplemente corresponde a las expectativas de las personas.

0

Inherit boost :: noncopyable (privadamente) en patrón de clase singleton que para definir la construcción de copia privada y el operador de asignación.

Cuestiones relacionadas