La respuesta es la misma que Copy Constructor. Si una clase no contiene punteros, entonces no hay necesidad de escribir el operador de asignación y copiar el constructor. El compilador crea un constructor de copia predeterminado y operadores de asignación para cada clase. El constructor de copia creado por el compilador y el operador de asignación pueden no ser suficientes cuando tenemos punteros o cualquier asignación de recursos en tiempo de ejecución, como un identificador de archivo, una conexión de red, etc. Por ejemplo, considere el siguiente programa.
#include<iostream> using namespace std; // A class without user defined assignment operator class Test { int *ptr; public: Test (int i = 0) { ptr = new int(i); } void setValue (int i) { *ptr = i; } void print() { cout << *ptr << endl; } }; int main() { Test t1(5); Test t2; t2 = t1; t1.setValue(10); t2.print(); return 0; }
La salida del programa anterior es «10». Si echamos un vistazo a main(), modificamos ‘t1’ usando la función setValue(), pero los cambios también se reflejan en el objeto ‘t2’. Este tipo de cambios inesperados causan problemas.
Dado que no hay un operador de asignación definido por el usuario en el programa anterior, el compilador crea un operador de asignación predeterminado, que copia ‘ptr’ del lado derecho al lado izquierdo. Entonces, ambos ‘ptr’ comienzan a apuntar a la misma ubicación.
Podemos manejar el problema anterior de dos maneras.
1) No permitir la asignación de un objeto a otro objeto. Podemos crear nuestro propio operador de asignación ficticio y hacerlo privado.
2) Escriba su propio operador de asignación que haga una copia profunda.
Lo mismo es cierto para Copy Constructor.
El siguiente es un ejemplo de operador de asignación de sobrecarga para la clase anterior.
#include<iostream> using namespace std; class Test { int *ptr; public: Test (int i = 0) { ptr = new int(i); } void setValue (int i) { *ptr = i; } void print() { cout << *ptr << endl; } Test & operator = (const Test &t); }; Test & Test::operator = (const Test &t) { // Check for self assignment if(this != &t) *ptr = *(t.ptr); return *this; } int main() { Test t1(5); Test t2; t2 = t1; t1.setValue(10); t2.print(); return 0; }
Producción
5
También deberíamos agregar un constructor de copia a la clase anterior, de modo que las declaraciones como «Prueba t3 = t4;» tampoco causa ningún problema.
Tenga en cuenta la condición if en el operador de asignación. Mientras sobrecargamos el operador de asignación, debemos verificar la autoasignación. De lo contrario, asignarse un objeto a sí mismo puede generar resultados inesperados (ver esto ). La verificación de autoasignación no es necesaria para la clase ‘Prueba’ anterior, porque ‘ptr’ siempre apunta a un número entero y podemos reutilizar la misma memoria. Pero, en general, es una práctica recomendada realizar una verificación de autoasignación.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA