2010-08-06 15 views
7
#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS 
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ 
    TypeName(const TypeName&);       \ 
    void operator=(const TypeName&) 

Estoy leyendo el código fuente abierto de Google. ¿Por qué copiar el constructor y el operador de asignación no están permitidos?¿Por qué copiar el constructor y el operador de asignación no están permitidos?

+1

Se les llama "copia constructor" y "operador de asignación". No existe tal cosa como un constructor de asignaciones. – Sjoerd

+2

Los llamaría "constructor" y "operador de asignación" o "constructor de copia" y "operador de asignación de copia" –

+2

No llamaría al MALVADO, ese tipo de colores los daría una mala imagen. Simplemente deshabilítelos como boost does: boost :: noncopyable –

Respuesta

12

Para evitar instancias de la clase que se está copiando o asignando. La mayoría de las clases no deberían permitir la copia. Considere, por ejemplo, una clase de Cuenta bancaria: si está escribiendo software para un banco, no estarán muy contentos si crea copias de cuentas y luego aplica créditos y débitos a esas diferentes copias.

+0

Ejemplo perfecto. ¡Cómo me gustaría que lo permitieran :) !!!! – DumbCoder

+0

+1 .... @DumbCoder si fueras el codificador del software de ese banco, ¡sería posible! – KedarX

+0

@Neil Butterworth: ¿Por qué no utilizar un singleton en su lugar? – MainID

1

Si su tipo contiene puntero o miembros de referencia, o no tiene sentido semántico para que se copie (por ejemplo, tiene un identificador de recurso que debe liberarse en el destructor), es una buena práctica desactivar el constructor de copia y operador de asignación. En C++ 0x (por ejemplo, en g ++ 4.4 o posterior en -std = C++ modo 0x) puede declararlos eliminados. En los compiladores más antiguos, simplemente los declaras privados y no implementados.

7

El problema con el constructor de copias y el operador de asignación de copias es que el compilador genera implementaciones automáticamente si no se declaran explícitamente.

Esto puede causar fácilmente problemas involuntarios. Si una clase tiene un destructor no trivial, casi siempre necesita proporcionar sus propias implementaciones para el constructor de copias y el operador de asignación de copias también (este es el Law of the Big Three) ya que los generados por el compilador por defecto usualmente harán lo incorrecto.

Violar la ley del Big Three a menudo conduce a errores tales como el doble libre de miembros de datos y la corrupción de la memoria. No es raro que surjan este tipo de errores porque el autor de la clase nunca se molestó en pensar en el comportamiento de copiado y porque es fácil para los consumidores copiar objetos involuntariamente.

A menos que el autor de la clase realmente haya pensado en cómo copiar correctamente las instancias de esa clase (o a menos que la clase tenga un destructor trivial), es mejor rechazar explícitamente la copia para evitar posibles problemas. La implementación de la capacidad de copiado podría diferirse hasta que exista una necesidad real.

+4

¡Eso se está convirtiendo en la "Ley de los Cinco Grandes" con el próximo estándar C++ 0x con la adición del Move Constructor/Assignment! – David

+1

@David: El operador de movimiento/operador de asignación de movimiento será opt-in (el compilador no los generará si los omite). – jamesdlin

+0

Tiene razón, pero si le importa el rendimiento, también se los proporcionará. – David

Cuestiones relacionadas