2011-04-09 16 views
13

¿El generador de asignaciones generó una guardia contra la autoasignación?Operador de asignación: autoasignación

class T { 

    int x; 
public: 
    T(int X = 0): x(X) {} 
}; 

int main() 
{ 
    T a(1); 
    a = a; 
} 

¿Siempre tengo que protegerme contra la autoasignación incluso cuando los miembros de la clase no son de tipo puntero?

+1

No, no hay nada de malo en eso. Y no creo que haya algo contra lo que "proteger", realmente. EDIT: ¿Estás hablando de un copy-constructor? –

+2

Si los miembros de la clase no son punteros/tipos inteligentes, la respuesta es no. No hay necesidad de protegerse contra eso. El comportamiento es el mismo que para POD (datos antiguos simples) en ese caso ... – 0xC0000022L

Respuesta

12

¿El generador de asignaciones genera la protección del operador contra la auto asignación?

No, no es así. Simplemente realiza una copia de miembro a miembro, donde cada miembro es copiado por su propio operador de asignación (que también puede ser declarado por el programador o generado por el compilador).

¿Siempre tengo que protegerme contra la autoasignación incluso cuando los miembros de la clase no son de tipo puntero?

No, no lo hace si todos los atributos de su clase (y por lo tanto de ellos) son POD-types.

Al escribir sus propios operadores de asignación, es posible que desee verificar la autoasignación si desea preparar su clase para el futuro, incluso si no contienen punteros, y otros. También considere the copy-and-swap idiom.

+1

Añadir, eliminar o cambiar los miembros de datos requiere volver a visitar op = (entre otros) de todos modos, por lo que una comprobación de autoasignación innecesaria no gana nada como en lo que respecta a la protección del futuro. –

+0

@Fred Nurk: Tienes toda la razón. Desafortunadamente, volver a visitar 'operator =' para los atributos nuevos o modificados no garantiza que el desarrollador haga Do The Right Thing ™. – Johnsyweb

+2

@Johnsyweb: Agregar una verificación de autoasignación innecesaria tampoco garantiza que el mantenedor hará lo correcto, pero es más probable que confunda a alguien que sí sabe lo que está haciendo. Por ejemplo: "innecesario" es importante aquí, porque los tipos costosos de copiar que se autoasignan con frecuencia (raros) se beneficiarían del cheque, aunque no sería estrictamente necesario. –

4

Esto es fácil de comprobar empíricamente:

#include <iostream> 
struct A { 
    void operator=(const A& rhs) { 
    if(this==&rhs) std::cout << "Self-assigned\n"; 
    } 
}; 

struct B { 
    A a; 
}; 

int main() 
{ 
    B b; 
    b = b; 
} 
+1

¡Agradable! Eso sin duda demuestra el comportamiento del compilador * actual *. – Johnsyweb

-1
class T { 
    int x; 
public: 
    T(int X = 0): x(X) {} 
// prevent copying 
private: 
    T& operator=(const T&); 
}; 
+1

No me parece que cpx quisiera desactivar el operador de asignación. (S) él quería usarlo, pero tenía una pregunta sobre autoasignación. (Además, tu código tenía un error tipográfico). –

Cuestiones relacionadas