Zuweisungsoperator für "tiefe Kopien"?!
-
Gibt es sowas in "elegant"? Oder muss ich jedes Element von Hand kopieren?
class Klasse1 { Klasse1(); ~Klasse1(); private: Klasse2 obj; };void Klasse1::operator= (const Klasse1& ref) { if (this == &ref) return; *this = *ref; }... Klasse1* test = new Klasse1(); Klasse1* test2 = test; delete test; ...Das ist doch nur eine "flache Kopie", oder? Sprich "copy by reference"?! Ich war der Meinung, dass obj angelegt aber nach delete test auch wieder gelöscht wird. Wie ist es wirklich?
-
class Klasse1 { Klasse1(); ~Klasse1(); private: Klasse2 obj; };Falls Klasse2 einen eigenen Zuweisungs-Operator und Copy-Konstruktor hat, brauchst du diese Funktionen für Klasse1 überhaupt nicht anzulegen. Das macht der Compiler automatisch für dich.
Dieser Code hier:
void Klasse1::operator= (const Klasse1& ref) { if (this == &ref) return; *this = *ref; }erzeugt eine Endlosrekursion. Schlechte Idee!
... Klasse1* test = new Klasse1(); Klasse1* test2 = test; delete test; ...Du legst hier eine Kopie des Zeigers an. Es gibt in deinem Beispiel nur ein einziges Objekt, das mit dem Aufruf von delete test wieder gelöscht wird.
-
Der operator= liefert immer eine Referenz der Klasse zurück. Zudem brauchst du einen operator= nur wenn du einen Zeiger in der Klasse hast. Der Rückgabewert von operator= ist letztendlich immer eine Referenz auf *this:
Klasse1& Klasse1::operator= (const Klasse1& ref) { if (this == &ref) return *this; // Wiese allen Datenelementen einen Wert zu: obj = ref.obj; return *this; }Wobei du hier noch operator= als friend von Klasse1 deklarieren musst. Wenn du nur den Inhalt eines Zeigers kopieren willst und nicht eine ganze Liste (wo noch einiges mehr nötig ist um eine tiefe Kopie zu erreichen), geht das so:
*pObj = *ref.pObj;
-
Vellas schrieb:
Zudem brauchst du einen operator= nur wenn du einen Zeiger in der Klasse hast.
<klugscheißen>
Ist nicht ganz korrekt. Gilt nur für den Fall, daß du wirklich ein Deep-Copy brauchst.
</klugscheißen>Vellas schrieb:
Wobei du hier noch operator= als friend von Klasse1 deklarieren musst.
Nö! Komplett überflüssig.
-
Z2 schrieb:
Nö! Komplett überflüssig.
Doch, weil ich im operator= auf ein private-Element (obj) der Klasse zugreife. Könnte man aber natürlich dadurch umgehen, wenn es für dieses Objekt eine get-Methode gibt.
-
Vellas schrieb:
Z2 schrieb:
Nö! Komplett überflüssig.
Doch, weil ich im operator= auf ein private-Element (obj) der Klasse zugreife.
Trotzdem Schwachsinn - operator= ist immer Member seiner Klasse, also hat er automatisch alle nötigen Rechte.
-
Ops, stimmt. Ich habe an Operatoren allgemein gedacht als ich das schrieb.

-
Du rufst von einer Memberfunktion der Klasse1 eine public Memberfunktion eines Datenmembers von Klasse1 auf. Dazu ist keine friend-Deklaration notwendig.
Edit: zu spät

-
Vellas schrieb:
Zudem brauchst du einen operator= nur wenn du einen Zeiger in der Klasse hast.
<klugscheißen>
Ist nicht ganz korrekt. Gilt nur für den Fall, daß du wirklich ein Deep-Copy brauchst.
</klugscheißen><klügerscheißen>Wenn der Default Assignment Op nicht zureicht oder nicht verfügbar ist<klügerscheißen>
-
Z2 schrieb:
Du rufst von einer Memberfunktion der Klasse1 eine public Memberfunktion eines Datenmembers von Klasse1 auf. Dazu ist keine friend-Deklaration notwendig.
Edit: zu spät

Ja, habe aber auch das Klasse1:: übersehen, weil ichs nur kopiert habe zum umschreiben.
@CStoll: Schwachsinn sicher nit, ein einfacher Hinweis wo mein Fehler lag hätte gereicht.
