Klasse Operatoren
Machte ich die folgenden Operatoren überladen test:
#include <iostream>
#include <string>
using namespace std;
class TestClass
{
string ClassName;
public:
TestClass(string Name)
{
ClassName = Name;
cout << ClassName << " constructed." << endl;
}
~TestClass()
{
cout << ClassName << " destructed." << endl;
}
void operator=(TestClass Other)
{
cout << ClassName << " in operator=" << endl;
cout << "The address of the other class is " << &Other << "." << endl;
}
};
int main()
{
TestClass FirstInstance("FirstInstance");
TestClass SecondInstance("SecondInstance");
FirstInstance = SecondInstance;
SecondInstance = FirstInstance;
return 0;
}
Dem Zuweisungsoperator verhält sich wie erwartet, die Ausgabe der Adresse von der anderen Instanz ist.
Nun, wie würde ich eigentlich zuweisen etwas von der anderen Instanz? Zum Beispiel so etwas wie dieses:
void operator=(TestClass Other)
{
ClassName = Other.ClassName;
}
- Sie brauchen auch keine, aber es sieht immer noch seltsam, dass man einen Zuweisungsoperator und einen Destruktor, aber kein copy-Konstruktor. Gemäß der Regel von Drei, wenn Sie benötigen, müssen Sie wahrscheinlich alle drei.
- Natürlich. Dies ist nur eine test-code, though.
- Noch, Reflexe kick, wenn ich sehe, dass. Ich habe auch bemerkt, dass Sie an einem
std::string
Objekt pro Exemplar stattconst
Referenz. Möchten Sie vielleicht zu Lesen this.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den code, den Sie gezeigt haben, dass es tun würde. Niemand würde denken, dass es eine besonders gute Umsetzung, obwohl.
Dies entspricht dem, was erwartet wird von einem Zuweisungs-operator:
BTW, Sie sprechen über "andere Klasse", aber Sie haben nur eine Klasse und mehrere Instanzen der Klasse.
swap()
member-Funktion und Anruf dass. Dennoch, das ist besser, als die Zuordnung.Den traditionellen kanonischen form der Zuweisungsoperator sieht aus wie dieser:
(Sie nicht wollen, zu rufen den copy-Konstruktor, Zuweisung, auch) und es gibt einen Verweis auf
*this
.Eine naive Implementierung würde zuordnen jedes Daten-Mitglied einzeln:
(Beachten Sie, dass dies genau das ist, was der compiler-generierte Zuweisungsoperator tun würde, also ist es ziemlich sinnlos zu überladen ist. Ich nehme es, dass dies für die Ausübung, aber.)
Ein besserer Ansatz wäre zu beschäftigen Copy-And-Swap-idiom. (Wenn Sie feststellen, GMan Antwort zu überwältigend, zu versuchen mir, das ist weniger erschöpfend.
:)
) Beachten Sie, dass C&S beschäftigt, und die Kopie-Konstruktor und Destruktor zu tun, Zuordnung und erfordert daher das Objekt übergeben werden, wird pro Kopie, als Sie hatten in Ihrer Frage:ninja edit
weil Sie die Veränderungen, die Ben war, darauf hindeutet, als er vorschlug, Sie.fast alles gesagt, ein paar Anmerkungen:
if (&other != this) //assign
<shameless_plug>
Wir haben auch einen operator überladen FAQ hier auf jetzt ALSO: stackoverflow.com/questions/4421706/operator-overloading.</shameless_plug>
swap()
swaps der eigentliche Zeiger? wenn nicht, sehe ich nicht, wie es keinen zusätzlichen overhead. Angenommen, Sie sind zuweisen von 2 Zeichenfolgen von gleicher Länge. In den "traditionellen" Ansatz, den Sie kopieren Sie einfach den Speicher. In C&S, Sie neuen Speicher, kopieren und freigeben. Bin ich etwas fehlt?std::vector
swapping swap zwei Zeiger. Im Vergleich zu den O(N) zu kopieren und die O(VeryLooong) der Verteilung, dies ist neglectable.)Traditionnaly der Zuweisungsoperator und der copy-Konstruktor definiert werden, übergeben Sie eine const-Referenz, und nicht eine Kopie von Wert-Mechanismus.
EDIT: ich korrigiert, da hatte ich code, der nicht die Rückkehr der TestClass& c.f. @sbi 's Antwort)
Sind Sie richtig darüber, wie Sie zu kopieren Sie den Inhalt aus der anderen Klasse. Einfache Objekte können nur zugewiesen werden, mit
operator=
.Jedoch vorsichtig sein in Fällen, wo
TestClass
enthält Zeiger-Mitglieder-wenn Sie nur ordnen Sie die Zeiger mitoperator=
, dann beide Objekte Zeiger zeigt auf den gleichen Speicher, das kann nicht sein, was Sie wollen. Sie können stattdessen müssen sicherstellen, dass Sie weisen Sie einige neue Speicherkarte und kopieren Sie die Spitzen-zu-Daten in es so dass beide Objekte haben Ihre eigene Kopie der Daten. Denken Sie daran, Sie müssen auch richtig freigeben der Speicher bereits gezeigt, durch den zugewiesen-zu-Objekt, bevor Sie die Zuweisung eines neuen Blocks für die kopierten Daten.Durch die Art und Weise, sollten Sie vielleicht erklären
operator=
wie diese:Ist dies der Allgemeinen Konvention verwendet, wenn eine überlastung
operator=
. Die return-Anweisung ermöglicht die Verkettung von Aufgaben (wiea = b = c
) und die übergabe der parameter durchconst
Referenz vermeidet das kopierenOther
auf dem Weg in die Funktion aufrufen.