2 Fragen zu dynamic_cast
-
1. Wirft dynamic_cast ne exception, oder gibts 0 zurück, wenn die Typen nicht umgewandelt werden können?
2. Ist dynamic_cast teuer (muss es in einer oft aufgerufenen Funktion einsetzen, in einem Zeitintensiven Programm)?
-
Gibt 0 zurück.
Ja ist ziemlich teuer. dynamic_cast ist obendrein schlechter Stil, bzw. lässt es sich häufig gut vermeiden, indem man virtuelle Methoden benutzt.
-
zu 1): ja und nein.
Wenn Du nen Pointer castest dann gibt er bei nem Fehlschlag 0 zurück. Bei ner Referenz fliegt bad_cast. Denn es gibt keine Nullreferenzen (*flame*).
-
-
The value of a failed cast to pointer type is the null pointer. A failed cast to reference type throws a bad_cast Exception.
-
Ja, ist teuer (im Vergleich zu anderen Casts) und sollte vermieden werden.
-
-
Stimmt, an Referenzen hab ich jetzt gar nicht gedacht.
-
Ichie schrieb:
1. Wirft dynamic_cast ne exception, oder gibts 0 zurück, wenn die Typen nicht umgewandelt werden können?
2. Ist dynamic_cast teuer (muss es in einer oft aufgerufenen Funktion einsetzen, in einem Zeitintensiven Programm)?
Bei einem Referenz-cast wird bad_cast geworfen, bei einem Pointer-cast wird null zurückgegeben. Es könnte auch teuer werden, da dynamic_cast nur mit polymorphen-Typen arbeitet. Zusätzlich muss RTTI eingeschaltet sein, zufolge könnte ein zusätzlicher Overhead entstehen. Das ganze ist aber Implementierungsspezifisch.
-
Optimizer schrieb:
Gibt 0 zurück.
Das heist gibt 0 zurück sofern wenn du 2 Pointer castest, wenn es 2 Referenzen sind dann wird eine bad_cast Exception geworfen.
Optimizer schrieb:
Ja ist ziemlich teuer. dynamic_cast ist obendrein schlechter Stil, bzw. lässt es sich häufig gut vermeiden, indem man virtuelle Methoden benutzt.
Schlechter Stil? naja der Basis Klasse eine virtual Funktion passen die da nicht hin gehört ist auch nicht viel besser! und viel schnell dynamic_cast ist hängt stark von deiner Hirarchie ab. Wenn die nicht kompliziert ist, also zum Beispiel 2 Level hat und keine Mehrfachvererbung dann läuft dynamic_cast auf einen Vergleich von 2 Pointern heraus.
-
Irgendwer schrieb:
Das heist gibt 0 zurück sofern wenn du 2 Pointer castest, wenn es 2 Referenzen sind dann wird eine bad_cast Exception geworfen.
Tja, für den 4. Platz gibt's nichtmal mehr ne Medaille. :p
-
Irgendwer schrieb:
Optimizer schrieb:
Ja ist ziemlich teuer. dynamic_cast ist obendrein schlechter Stil, bzw. lässt es sich häufig gut vermeiden, indem man virtuelle Methoden benutzt.
Schlechter Stil? naja der Basis Klasse eine virtual Funktion passen die da nicht hin gehört ist auch nicht viel besser! und viel schnell dynamic_cast ist hängt stark von deiner Hirarchie ab. Wenn die nicht kompliziert ist, also zum Beispiel 2 Level hat und keine Mehrfachvererbung dann läuft dynamic_cast auf einen Vergleich von 2 Pointern heraus.
dynamic_cast ist bei der Implementierung meines Compilers eine verdammt langsame Operation, die sogar auch noch String-Vergleiche bemüht. Und auch wenn ich Mehrfachvererbung vermeide, habe ich meistens trotzdem (oder genau deswegen) Vererbung über mehr als 2 Level.
Natürlich soll man keine virtuelle Methode in der Basisklasse "erzwingen". Aber ich habe schon genug Code gesehen nach dem Motto:
if( dynamic_cast<... ) ...; else if( dynamic_cast<... ) ...;
Und das finde ich mal wirklich unschön und wenig wartungsfreudig. Meistens passt eine virtuelle Methode für so eine Unterscheidung ganz gut, erzwingen muss man meistens nichts.
Ich empfehle generell, alle Arten von casts so gut wie möglich zu vermeiden und bei dynamic_cast gelingt das IMHO besonders oft.
-
Ich habs mir schon gedacht, aber Robert C Martin beschreibt in seinem Acyclic Visitor Pattern eine Möglichkeit mit dynamic_cast die endlosen Abhängigkeiten des Visitor Patterns zu umgehen. Ist theoretisch bestimmt nicht schlecht, aber in Funktionen die dauernd aufgerufen weren wohl eher
-
dynamic_cast ist bei der Implementierung meines Compilers eine verdammt langsame Operation, die sogar auch noch String-Vergleiche bemüht. Und auch wenn ich Mehrfachvererbung vermeide, habe ich meistens trotzdem (oder genau deswegen) Vererbung über mehr als 2 Level.
Meiner vergleicht einfach die Vtable Pointer, also so etwas in der Art:
template<class T> T*dynamic_cast(T*t){ switch(t->vtable){ case A_vtable: return t; case B_vtable: return (T*)(((char*)t)+6); default: return 0; } }
Wenn das ganz klein ist dann inline er es auch noch.
-
Das kann nur in Ausnahmefällen funktionieren.
Wenn du etwas nach "Point" castest, dann muss er auch sein OK liefern, wenn das Objekt vom Typ "SuperMasterPoint" ist, abgeleitet von "MasterPoint", abgeleitet von "Point".
Solche trivialen Fälle, wie du gerade genannt hast, sind selten. Jede Klasse hat seine eigene vtbl und trotzdem sind sie alle Points.