Implementieren der Überladung von Zuweisungsoperatoren in C++
In diesem Artikel werden verschiedene Methoden zum Implementieren der Überladung von Zuweisungsoperatoren in C++ erläutert.
Verwenden Sie Kopierzuweisungsoperator
, um den überladenen Zuweisungsoperator in C++ zu implementieren
C++ bietet die Funktion zum Überladen von Operatoren, eine übliche Methode zum Aufrufen benutzerdefinierter Funktionen, wenn ein integrierter Operator für bestimmte Klassen aufgerufen wird. Diese Funktionen sollten einen speziellen Namen haben, der mit operator
gefolgt vom spezifischen Operatorsymbol selbst beginnt. Beispielsweise kann ein benutzerdefinierter Zuweisungsoperator mit der Funktion operator=
implementiert werden. Der Zuweisungsoperator sollte im Allgemeinen einen Verweis auf seinen linken Operanden zurückgeben. Beachten Sie, dass der Compiler automatisch einen generiert, wenn der Benutzer den Operator für die Kopierzuweisung nicht explizit definiert. Die generierte Version ist durchaus in der Lage, wenn die Klasse keine Datenelemente enthält, die manuell im Heapspeicher zugewiesen wurden. Es kann sogar die Array-Mitglieder behandeln, indem jedes Element den entsprechenden Objektelementen zugewiesen wird. Es weist jedoch Mängel beim Umgang mit dynamischen Speicherdatenelementen auf, wie im folgenden Beispielcode gezeigt.
#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);
}
Ausgabe:
Buddy Rich
Buddy Rich
Jay Roach
Buddy Rich
Jay Roach
Jay Roach
Liam White
Liam White
Der obige Code definiert nur Kopierkonstruktor
explizit, was zu einem falschen Verhalten führt, wenn dem Objekt P3
Objektinhalte P1
zugewiesen werden. Beachten Sie, dass der zweite Aufruf der Funktion P1.renamePerson
die Datenelemente des Objekts P3
nicht hätte ändern dürfen, dies jedoch tat. Die Lösung hierfür besteht darin, einen überladenen Zuweisungsoperator zu definieren, d. H. Einen Kopierzuweisungsoperator. Das nächste Code-Snippet implementiert die Version der Klasse Person
, die kopieren kann, um die beiden Objekte derselben Klasse korrekt zuzuweisen. Beachten Sie jedoch, dass die Anweisung if
in der Kopierzuweisungsfunktion garantiert, dass der Operator auch dann ordnungsgemäß funktioniert, wenn das Objekt sich selbst zugewiesen ist.
#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);
}
Ausgabe:
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