Copy-Konstruktor
-
Hallo zusammen...
Wenn ich ne Klasse hab, in der ich nen Copy-Konstruktor aufrufe,
wird dann automatisch (wenn nötig) die richtige Unterklasse aufgerufen?class ClazzA{ } class ClazzB : public ClassA{ } class Clazz{ public: void method(ClassA* clazz); private: ClazzA* clazz; }void Clazz:method(ClassA* clazz){ this->clazz = new ClazzA(*clazz); }Was passiert, wenn ich nen ClazzB-Object übergebe?
Ruft er dann den Copy-Konstruktor von ClazzB auf?Gruß,
CSpille
-
Der Comiler tut das was du ihm sagst:
new ClazzA(*clazz);=> Erzeugt ein Objekt der Klasse ClazzA und initialisiert sie mit den Werten
von clazz.Ich nehme mal an, dass du das Objekt clazz kopieren/klonen möchtest. Hierzu musst du dir eine virtuelle Clone-Funktion in ClazzA schreiben, die den Kopierkonstruktor von ClazzA aufruft und in ClazzB die Funktion überschreiben und dort den Kopierkonstruktor von ClassB aufrufen.
In ClassZ rufst du dann clazz->clone () auf und bekommst dann die gewünschte Kopie...
-
So, wie ich das verstanden hab', dann ruft er auch bei einem clazzB-Objekt den CopyCtor von clazzA auf, da Du ja explizit ein classA-Objekt erstellst. Wenn Du daraus allerdings eine Template-Member-Funktion machst, dann sollte je übergebenen Objekt der entsprechende CopyCtor aufgerufen werden, also:
template<class T> void method(T* obj) { this->clazz = new T(*obj); }Soweit ich das aber nun verstanden habe müsstest Du den CopyCtor evtl. als virtual deklarieren, damit das problemlos klappt.
@diejenigen, die mehr Ahnung haben: Falls ich mich irre, dann bitte nicht steinigen, sondern nur korrigieren.

-
Ich hab auch schon an einen virtuellen Kostruktor gedacht,
aber ich meine gelesen zu haben, dass sowas sinnlos ist...Das mit der virtuellen Methode clone hätte ich sonst auch gemacht...
Gruß,
CSpille
-
mantiz schrieb:
Soweit ich das aber nun verstanden habe müsstest Du den CopyCtor evtl. als virtual deklarieren, damit das problemlos klappt.
Leider nicht
http://www.research.att.com/~bs/bs_faq2.html#virtual-ctor
Kurt
-
virtuellen Kostruktor
in C++ gibt es ihn nicht, aber bei SW Designs wird oft davon gesprochen,
Man kann sich aehnliches bauen ... clone methoden iss eine variante, Objectfabriken die andere ...
Ciao ...
-
@RHBaum
Viele Wege führen nach Rom... aber eine Fabrik zu implementieren um ein Objekt einfach nur zu kopieren ist ziemlich übertrieben.
-
keiner sagt das Objektfabriken kompliziert sein muessen ...
simple Fabrik-Funktionen gehoeren immerhin auch dazu ....Behaupte aber auch nich dass ers unbedingt machen sollte ...
sondern nur, dass er ueber diesen begriff stolpern wird sobald er nach dem begriff "virtuelle Konstruktoren" intensiver suchen wird ...
Bevor wir hier ihm ueberhaupt tips geben koennen, was und wie er implementieren sollte, fehlen uns ne menge infos noch ...
Weisst du, ob seine kopie von der Klasse ueberhaupt wirklich notwendig iss ??
Ich nehme mal an, dass du das Objekt clazz kopieren/klonen möchtest.
nee glaub er will das clazz in Classz seinen wahren typ mitbekommt ...
class ClazzA { public: virtaul ~ClazzA(){} // niemals virtuellen destruktor vergessen, wenn man was als basisklasse vorsieht virtual ClazzA * clone() const = 0; // Falls ClazzA nicht abstract, sondern ne default Impl sein soll, dann cannst auch so implementieren virtual ClazzA * clone() const { return new ClazzA(*this); // wenn CCtor von classz A vorhanden ... geht natuerlich hier auch jeder beliebige ... } } class ClazzB : public ClassA { // CCtor mal private lassen ClazzB(const ClazzB & rx) ... // CCtor implementieren public: virtaul ~ClazzB(){} virtual ClazzA * clone() const { return new ClazzB(*this); } } class Clazz{ public: void method(const ClassA* aclazz) { // allte clazz Instanz ggf. loeschen ... oder noch besser, std::auto_ptr verwenden fuer pointer aggregationen... clazz = aclazz.clone(); // hier iss nu volkommen wurscht, was aclazz in wirklichkeit ist ... } private: ClazzA* clazz; }Nur als so als vorschlag ....
Ciao ...
-
Danke RHBaum,
wie das mit dem clonen gemeint war ist mir schon klar...
Halt wie in Java nur, dass die Methode noch mit Hilfe des
Copy-Konstruktor implementiert wird und public ist.Gruß,
CSpille
-
@RHBaum
Wenn jemand von einer Fabrik redet setze ich immer die allgemeine Definition voraus und erwarte nicht dass man damit eine vereinfachte, abgespeckte und bis zu Clone-Funktionen optimiere "Fabrik" meint.

Ansonsten würde ich diese Funktionsdeklaration in ClazzB bevorzugen:
virtual ClazzB * clone() constum die Clone-Funktion von ClazzA zu überschreiben... spart einem das lästige casten, wenn einem der wirkliche Datentyp ausnahmsweise mal bekannt ist...
nee glaub er will das clazz in Classz seinen wahren typ mitbekommt ...
*leicht verwirrt*
Ok.. und ich dachte es geht hier um das Thema wie kopiere ich ein Objekt über die Schnittstelle der Oberklasse.
-
Hallo Mathias,
du darfst doch die Signatur der Methode nicht ändern...
Oder sehe ich das falsch?Gruß,
CSpille
-
Die Signatur ist an dieser Stelle nicht entscheident (Die Funktion der Basisklasse besitzt so oder so eine andere Signatur als die der abgeleiteten Klasse).
Der Knackpunkt ist an der Stelle die Tabelle mit den virtuellen Funktionen, die für jedes Objekt gehalten wird. Solange der Rückgabetyp der abgeleiteten Klasse, die Schnittstelle es Rückgabetyps der Oberklasse besitzt, kann die Funktion der abgeleiteten Klasse in die Tabelle eingetragen werden.
Der in der Unterklasse verwendete Typ des Rückgabewerts ist also nicht frei gewählbar. Es kann nur der Typ verwendet werden, der in der Oberklasse verwendet wird oder Typen, die von diesem Typ abgeleitet sind.
-
Cool...
Wußte ich auch noch nicht...
In Java geht es jedenfalls nicht
Gruß,
CSpille
-
In C++ hat man mehr Möglichkeiten wie mit Java etwas zu implementieren, dafür läßt Java viele Fehler die in C++ möglich sind einfach nicht zu.