Implementar la sobrecarga del operador de asignación en C++
Este artículo explicará varios métodos de cómo implementar la sobrecarga del operador de asignación en C++.
Utilice el operador de asignación de copia
para implementar el operador de asignación sobrecargado en C++
C++ proporciona la función de sobrecargar operadores, una forma común de llamar a funciones personalizadas cuando se llama a un operador integrado en clases específicas. Estas funciones deben tener un nombre especial que comience con operador
seguido del símbolo del operador específico. Por ejemplo, se puede implementar un operador de asignación personalizado con la función denominada operador =
. El operador de asignación generalmente debe devolver una referencia a su operando de la izquierda. Tenga en cuenta que si el usuario no define explícitamente el operador de asignación de copia, el compilador genera uno automáticamente. La versión generada es bastante capaz cuando la clase no contiene ningún miembro de datos asignado manualmente en la memoria del montón. Incluso puede manejar los miembros del array asignando cada elemento a los miembros de objeto correspondientes. Sin embargo, tiene deficiencias cuando se trata de miembros de datos de memoria dinámica, como se muestra en el siguiente código de ejemplo.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
class Person {
public:
Person() {
name = new string;
surname = new string;
};
Person(string n, string s) {
name = new string(std::move(n));
surname = new string(std::move(s));
}
Person(Person &p) {
name = new string(*p.name);
surname = new string(*p.surname);
}
~Person() {
delete name;
delete surname;
}
void renamePerson(const string &n, const string &s) {
name->assign(n);
surname->assign(s);
};
void printPerson() { cout << *name << " " << *surname; }
private:
string *name;
string *surname;
};
int main() {
Person P1("Buddy", "Rich");
Person P2 = P1;
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
P1.renamePerson("Jay", "Roach");
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
Person P3;
P3 = P1;
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
P1.renamePerson("Liam", "White");
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
exit(EXIT_SUCCESS);
}
Producción :
Buddy Rich
Buddy Rich
Jay Roach
Buddy Rich
Jay Roach
Jay Roach
Liam White
Liam White
El código anterior define sólo constructor de copia
explícitamente, lo que da como resultado un comportamiento incorrecto cuando el contenido del objeto P1
se asigna al objeto P3
. Tenga en cuenta que la segunda llamada a la función P1.renamePerson
no debería haber modificado los miembros de datos del objeto P3
, pero lo hizo. La solución a esto es definir un operador de asignación sobrecargado, es decir, un operador de asignación de copia. El siguiente fragmento de código implementa la versión de la clase Person
que puede copiar y asignar correctamente los dos objetos de la misma clase. Sin embargo, observe que la instrucción if
en la función de copia-asignación garantiza que el operador funciona correctamente incluso cuando el objeto está asignado a sí mismo.
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
class Person {
public:
Person() {
name = new string;
surname = new string;
};
Person(string n, string s) {
name = new string(std::move(n));
surname = new string(std::move(s));
}
Person(Person &p) {
name = new string(*p.name);
surname = new string(*p.surname);
}
~Person() {
delete name;
delete surname;
}
Person &operator=(const Person &p) {
if (this != &p) {
*name = *(p.name);
*surname = *(p.surname);
}
return *this;
}
void renamePerson(const string &n, const string &s) {
name->assign(n);
surname->assign(s);
};
void printPerson() { cout << *name << " " << *surname; }
private:
string *name;
string *surname;
};
int main() {
Person P1("Buddy", "Rich");
Person P2 = P1;
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
P1.renamePerson("Jay", "Roach");
P1.printPerson();
cout << endl;
P2.printPerson();
cout << endl;
Person P3;
P3 = P1;
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
P1.renamePerson("Liam", "White");
P1.printPerson();
cout << endl;
P3.printPerson();
cout << endl;
exit(EXIT_SUCCESS);
}
Producción :
Buddy Rich
Buddy Rich
Jay Roach
Buddy Rich
Jay Roach
Jay Roach
Liam White
Jay Roach
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook