zu viel dynamic_cast??
-
Hallo!
Wenn ich eine Basis- und eine abgeleitete (Derived) Klasse habe und folgenden Code benutzen möchte:
[cpp] Basis object_basis; Derived object_derived1, object_derived2; object_basis = *(dynamic_cast<Basis*>(&object_derived)); object_derived2 = *(dynamic_cast<Derived*>(&object_basis)); [/cpp]
Funktioniert das, d.h. kann ich alle Eigenschaften und Funktionen der Klasse Derived auf das Objekt object_derived2 anwenden? Oder gehen mir die neuen Eigenschaften der abgeleiteten Klasse Derived verloren, da ich zu oft oder vielleicht zu unglücklich caste?
Ich habe nämlich genau an der Stelle in meinem Programm ein Problem und will wissen, ob der Fehler meiner Methode an obigem Beispiel liegt oder ob ich einen anderen Fehler in meiner Methode habe...
Danke!
Basti
-
Oder gehen mir die neuen Eigenschaften der abgeleiteten Klasse Derived verloren
Nein. Da geht ja nichts verloren bei einem dynamic_cast.
Aber du castest trotzdem ungünstig, weil du dynamic_cast da benutzt, wo du ihn nicht benutzen musst.
object_basis = *(dynamic_cast<Basis*>(&object_derived));
Das ist ein Up-Cast!
-
(Notiz an mich selbst: Originalposting genauer lesen...)
-
und dank slicing verlierst du alle daten von derived
richtig geht es mit referenzen:
mittels dynamic_cast kannst du den crosscast direkt machen, ohne über base zu gehen - aber immer daran denken: nicht by value sondern by reference (oder zeiger)
-
kingruedi schrieb:
Aber du castest trotzdem ungünstig, weil du dynamic_cast da benutzt, wo du ihn nicht benutzen musst.
object_basis = *(dynamic_cast<Basis*>(&object_derived));
Das ist ein Up-Cast!
Ich hab noch nie etwas von einem Up-Cast gehört... Kannst du mir vielleicht kurz erklären, warum der für mich hier besser ist?
-
Shade Of Mine schrieb:
richtig geht es mit referenzen:
mittels dynamic_cast kannst du den crosscast direkt machen, ohne über base zu gehen - aber immer daran denken: nicht by value sondern by reference (oder zeiger)meinst du, so?
[cpp]
Basis object_basis;
Derived object_derived1, object_derived2;
object_basis = (dynamic_cast<Basis>(&object_derived));
object_derived2 = &(dynamic_cast<Derived*>(&object_basis));
[/cpp](Kann ich eine Adresse überhaupt mit dem Referenzoperator benutzen??? Ich nehme an, nicht. Aber dann bin ich aus deiner Antwort leider nicht schlau geworden... Kannst du mir vielleicht ein kleines Beispiel geben?
)
-
nein
derived a; base *b=&a; //kein cast derived &d=dynamic_cast<derived&>(a);
was du machst ist immer wieder neue Objekte konstruieren, dann klappt das nicht.
-
kingruedi schrieb:
nein
derived a; base *b=&a; //kein cast derived &d=dynamic_cast<derived&>(a);
Kann ich dann immer noch auf NULL überprüfen?
z.B.if (&d){ } else{ }
-
s-bolz schrieb:
Kann ich dann immer noch auf NULL überprüfen?
Nein, wenn ein dynamic_cast mit Referenzen fehlschlägt fliegt eine Exception.
Denn eine Referenz kann nicht NULL sein.
-
Super! Vielen herzlichen Dank, ihr habt mir echt sehr weiter geholfen. Ich glaube, ich habe jetzt auch endlich ein Problem, an dem ich schon seit mehreren Tagen knabbere, verstanden und hoffe, ich kann es jetzt endlich lösen.
Basti
-
du musst keine Referenzen nehmen. Du kannst natürlich auch Pointer nehmen, dann fliegt keine Exception sondern NULL wird zurückgegeben.
-
kingruedi schrieb:
du musst keine Referenzen nehmen. Du kannst natürlich auch Pointer nehmen, dann fliegt keine Exception sondern NULL wird zurückgegeben.
Ich habe jetzt schon alles mit den Referenzen gemacht, das hat auch alles geklappt. Mit den Zeigern hatte ich das vorher bereits probiert, aber da hab ich das aus irgendeinem Grund nicht hinbekommen. Ich glaube aber, ich habe es jetzt verstanden...
Aber mal eine andere Frage:
Kann ich Vektoren auch als Rückgabewert einer Funktion definieren?
-
Kann ich Vektoren auch als Rückgabewert einer Funktion definieren?
warum sollte man es nicht können?
-
OK, das mit dem Vector zurückgeben (und übergeben) hab ich jetzt hingekriegt...
Kann ich es irgendwie bewerkstelligen, dass ich keine Kopie von dem zurückgegeben Vector anlegen muss, sondern den in der Funktion erstellten Vector in der aufrufenden Methode gleich weiterverwenden kann? ich habe versucht, Referenzen des Vectors als Rückgabewert (und auch als Übergabeparameter) zu definieren, jedoch hat das nicht geklappt. Geht das generell nicht oder hab ich das nur falsch gemacht?
P.S.: Nicht wundern, ich versuche mich in diesen Tagen das erste mal mit Vectoren...
-
Du kannst nur entweder hoffen, dass dein Compiler die Rückgabe wegoptimiert (RVO/NRVO, danach kann man suchen) oder die Funktion so umschreiben:
void getFoos(std::vector<Foo>& result) { result.push_back(Foo()); result.push_back(Foo()); result.push_back(Foo()); }
Und dann einen Vektor übergeben. Würde ich aber nur tun, wenns anders wirklich weh tut.
BTW: Wenn du bei der Basisklasse einer Hierarchie das Kopieren und Zuweisen verbietest, kannst du ganz sicher sein, dass kein Slicing passiert. Ist IMHO eine gute Konvention.