dynamic_cast



  • dynamic_cast prüft zuerst per RTTI, ob der Cast "Sinn" macht und führt dann einen static_cast durch, andernfalls wird 0 zurückgegeben.

    stimmt das ?



  • Hi,

    also irgendwie kommt mir der Satz sehr bekannt vor, fast, wie wenn ich ihn selbst im ZFX-Forum verfasst hätte. 😃

    Und ich würde immer noch sagen, dass das stimmt 🙂

    ChrisM

    PS: Mit Sinn machen mein(t)e ich, dass der Cast eindeutig und gültig ist, d.h. dass man nicht z.B. versucht, von Base* auf Sub1* zu casten, obwohl der Base* auf ein Sub2-Objekt zeigt.



  • Bei manchen Compilern muss man allerdings AFAIK eine zusätzliche Option einschalten damit der Cast richtig funktioniert. Wird dann im Zweifelsfall eh ne Warnung ausgegeben.



  • Hi,

    jo, RTTI sollte schon an sein 🙂

    ChrisM



  • Nein, das stimmt so nicht. Erstens wird nicht unbedingt ein static_cast druchgeführt, sondern ggf. der Pointer-Wert verändert, und zweitens wird nur bei Pointern im "Fehlerfall" 0 zurückgegeben, bei Referenzen wird ein std::bad_cast geworfen.

    Stefan.



  • Hi,

    was meinst du mit Pointerwert verändern? Sowas ist aber dann nur bei Casts von einer mehrfacherbenden Klasse zu einer ihrer Basisklassen der Fall.

    ChrisM



  • ChrisM schrieb:

    was meinst du mit Pointerwert verändern?

    dynamic_cast macht sachen die ein 'normaler' cast nicht kann. deshalb kannst du ihn auch nicht durch C casts ersetzen.

    denn ein dynamic_cast kann zB cross casts, down casts,...
    da muss zB jedesmal die vtable angepasst.



  • Hi,

    ja und? static_cast kann auch downcasten!!

    ChrisM



  • ChrisM schrieb:

    ja und? static_cast kann auch downcasten!!

    Nein, kann er nicht, oder jedenfalls nicht zuverlässig. static_cast kann, auf Verweise angewendet, lediglich dem Compiler einen anderen Typ auf's Auge drücken, jedoch nicht den Verweis anpassen, falls nötig.

    ChrisM schrieb:

    was meinst du mit Pointerwert verändern? Sowas ist aber dann nur bei Casts von einer mehrfacherbenden Klasse zu einer ihrer Basisklassen der Fall.

    Ich würde aus praktischen Gründen erwarten, daß das so stimmt. Man hat ja eine gewisse Vorstellung davon, wie das Speicherlayout bei Klassen realisiert wird. Tatsächlich aber ist dieses Layout nicht vom Standard definiert, also hängt es vom Compiler-Hersteller ab, ob dynamic_cast vielleicht in eigentlich ganz unverdächtigen Fällen "seltsame" Sachen macht. static_cast ist bei Up- und Downcasts aus diesem Grund immer unangebracht - selbst wenn man bei einem speziellen Compiler das erwartet Ergebnis erhält.

    Außerdem sagt die Verwendung des richtigen Casts auch dem Leser des Codes, was hier gemacht wird bzw. werden soll. Schon deshalb sollte man ihn auch verwenden.

    Stefan.



  • Hi,

    bei mir steht in der MSDN:

    The static_cast operator can be used for operations such as converting a pointer to a base class to a pointer to a derived class.

    Kannst ja nicht leugnen, dass das ein Downcast ist.

    Wenn du weißt, dass der Zeiger auf die Base der Sub-Instanz entspricht, dann kannst du den Cast auch sicher mit static_cast<Sub*>(pBase) durchführen und musst nicht dynamic_cast (laaaangsam) bemühen.

    Trotzdem sollte man zur Sicherheit natürlich eher dynamic_cast verwenden oder sowieso so wenig Downcasts wie möglich im design einplanen und eher auf Polymorphismus setzt, statt downzucasten und dann die Aktion durchzuführen (-> Open-Closed-Prinzip)

    ChrisM



  • DStefan schrieb:

    Nein, kann er nicht, oder jedenfalls nicht zuverlässig. static_cast kann, auf Verweise angewendet, lediglich dem Compiler einen anderen Typ auf's Auge drücken, jedoch nicht den Verweis anpassen, falls nötig.

    Doch, kann er. Du verwechselst ihn gerade mit dem reinterpret_cast. static_cast kann dann angewendet werden, wenn der Cast garantiert klappt, da er keine vorherige Überprüfung der Gültigkeit vornimmt. Während dynamic_cast im Fehlerfall eine Exception wirft bzw. einen Nullpointer zurückliefert, macht static_cast dann Mist (spricht: Undefiniertes Verhalten). Siehe Stroustrup, §15.4.2.1.



  • Hi,

    sag ich doch 😃

    ChrisM



  • Aber Struppi hat mehr Autorität als die MSDN 😉



  • Bashar schrieb:

    Doch, kann er. Du verwechselst ihn gerade mit dem reinterpret_cast. static_cast kann dann angewendet werden, wenn der Cast garantiert klappt, da er keine vorherige Überprüfung der Gültigkeit vornimmt. Während dynamic_cast im Fehlerfall eine Exception wirft bzw. einen Nullpointer zurückliefert, macht static_cast dann Mist (spricht: Undefiniertes Verhalten). Siehe Stroustrup, §15.4.2.1.

    Ich habe gerade keine Strousdrup da (wir sind echt fortschrittlich hier auffe Arbeit), aber wenn ich mich recht entsinne, ist ein static_cast nur gültig, wenn es eine implizite Konvertierung des Ausgangstyps zum Zieltyp gibt. Das gilt für Downcasts aber nicht. Erinnere ich mich falsch? Dann bitte ich um Entschuldigung.

    Stefan.



  • Es war andersrum soweit ich weiß, denn wenn es eine implizite Umwandlung gibt, braucht man ja den Cast nichtmehr.



  • DStefan schrieb:

    Ich habe gerade keine Strousdrup da (wir sind echt fortschrittlich hier auffe Arbeit), aber wenn ich mich recht entsinne, ist ein static_cast nur gültig, wenn es eine implizite Konvertierung des Ausgangstyps zum Zieltyp gibt.

    Bashar schrieb:

    Es war andersrum soweit ich weiß

    In der Tat.

    Prinzipiell ist ein static_cast also durchaus in der Lage downcasts zu machen. Sogar locker mit Delta-Arithmetik.
    Problematisch wirds bei Situationen wie:

    class A { public: virtual ~A(); };
    class B { public: virtual ~B(); };
    class D : public A, public B {};
    class E : public B {};
    
    B* gibMirEinB()
    {
    ...
    }
    int main()
    {
    B *bp = gibMirEinB();
    D *dp = static_cast<D*>(bp);
    }
    

    Das geht solange gibMirEinB ein D, B oder A liefert. Liefrt gibMirEinB aber ein E, dann wird das Programm zwar übersetzt, das Verhalten ist aber undefiniert.
    Ein dynamic_cast würde in dieser Situation das Programm retten und einen Nullpointer liefern.


Anmelden zum Antworten