PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++.NET]Kopierkonstruktor?


Gast
2006-07-05, 11:55:40
Ich bin gerade dabei, eine Managed Klasse zu schreiben, die einen Kopierkonstruktor enthalten soll. Auf den ersten Blick scheint .NET ja eine hervorragende Unterstützung hierfür anzubieten, mittels der Methode System::Object::MemberwiseClone(), die ein bequemes Erzeugen einer Objektkopie gestattet. Ich habe dann mal folgendes versucht:
public ref class EvilEnemy
{
// Copy-Konstruktor
EvildEnemy(EvilEnemy^ src);
//...
};

//...

EvilEnemy::EvilEnemy(EvilEnemy^ src)
{
this = (EvilEnemy^) src->MemberwiseClone();
}

aber da bekomme ich die Fehlermeldung, this sei kein L-Value. Kann es sein, daß .NET den Zuweisungsoperator für den this-Pointer nicht mehr unterstützt?

Ich habe das jetzt so gelöst, daß ich auf einen Copy-Konstruktor verzichte, und stattdessen eine statische Copy-Methode benutze:

public ref class EvilEnemy
{
//...
static void Copy(EvilEnemy^ dest, EvilEnemy^ src)
{
dest = (EvilEnemy^) src->MemberwiseClone();
}
};

aber besonders elegant erscheint mir das nicht. Es kann doch nicht sein, daß .NET keine Copy-Konstruktoren erlaubt (ohne daß man die Member alle von Hand einzeln kopieren muß)???

Gnafoo
2006-07-05, 12:12:37
Mit C++.Net habe ich keine Erfahrung. Aber mit C++ und C#. Von daher würde ich sagen, dass du entweder ICloneable implementieren solltest (wobei du in der Clone-Methode gerne auf MemberwiseClone() zurückgreifen kannst) oder den Copy-Konstruktor. Der Copy-Konstruktor muss dann aber die Werte aus dem anderen Objekt übernehmen und nicht sein eigenes Objekt mittels this überschreiben. (Wäre mir auch neu, dass das geht. Schließlich würde das aktuelle this-Objekt dabei ja gar nicht gelöscht werden.)

Ich persönlich würde einfach ICloneable implementieren. Das ist wohl für .NET die passende, Objekte zu klonen. Außerdem kannst du das dann auch über ein sauberes Interface machen, welches evtl. auch von anderen .NET-Klassen berücksichtigt werden kann.

Bei MemberwiseClone() solltest du aber beachten, dass zwar Zeiger auf Objekte kopiert werden, nicht aber die Objekte selber. Für Baumstrukturen etc. musst du die entsprechenden Objekte selber rekursiv kopieren.

Neomi
2006-07-05, 13:04:17
Du solltest ein Objekt auch einem anderen Objekt gleichen Typs zuweisen, nicht einem Zeiger auf ein solches Objekt.

this = ...; // falsch
*this = ...; // besser

Gast
2006-07-05, 13:23:03
Neomi[/POST]']Du solltest ein Objekt auch einem anderen Objekt gleichen Typs zuweisen, nicht einem Zeiger auf ein solches Objekt.

this = ...; // falsch
*this = ...; // besser*this = *src geht nicht, da erhalte ich die Meldung der Zuweisungsoperator sei nicht definiert.
Was das mit den Objekten angeht: vergiß nicht, es handelt sich um .NET. Und da ist irgendwie alles darauf ausgelegt, daß man Objekte gar nicht mehr direkt anspricht, sondern bis zum Erbrechen die Objektpointer^ und die automatische Speicherverwaltung exerziert. Ich seh schon kommen, daß statt
int i=5;
nur noch int ^i = gcnew System::Int32(5); erlaubt ist.

Expandable
2006-07-05, 17:50:42
Also das mit this (oder *this) = finde ich auch komisch, lieber wie gehabt pro Member eine Zuweisung. Abgesehen davon ist in Deiner Klassendefinition ein Tippfehler (EvildEnemy statt EvilEnemy), das sollte eigentlich auch eine Fehlermeldung erzeugen.