Unterschied dynamic/static cast



  • Gugelmoser schrieb:

    Was du wissen musst ist, dass dynamic_cast auf ein schlechtes Design hinweist, also ein schlechtes Design der Grund ist, dass du dynamic_cast brauchst.

    Ergänze in dem Satz mal ein "in der Regel" oder "meistens" 😉
    Außerdem gibt es auch Fälle in denen ein const_cast sinnvoll ist. :xmas1:

    Aber tendenziell gebe ich dir absolut recht. In den meisten Fällen sollte man wirklich nochmal überlegen, ob es auch wirklich sauber ist...



  • const_cast braucht man meist nur in 2 Fällen:
    .)Eine API, die nicht auf const-correctness achtet, wird verwendet.
    .)Non-const Memberfunktionen über die const-Versionen implementieren, um Redundanz zu vermeiden.



  • XSpille schrieb:

    Ergänze in dem Satz mal ein "in der Regel" oder "meistens"

    Einverstanden :p

    XSpille schrieb:

    Außerdem gibt es auch Fälle in denen ein const_cast sinnvoll ist.

    Hast du noch ein Beispiel?



  • Gugelmoser schrieb:

    Hast du noch ein Beispiel?

    Wir nehmen an, die const-Version von baz() ist eine ziemlich lange Methode.

    struct foo
    {
        bar const& baz() const;
    
        bar& baz()
        {
            return const_cast<bar&>(static_cast<foo const*>(this)->baz());
        }
    };
    


  • Gugelmoser schrieb:

    XSpille schrieb:

    Außerdem gibt es auch Fälle in denen ein const_cast sinnvoll ist.

    Hast du noch ein Beispiel?

    Ich dachte wenn man beipielsweise eine große Menge von Daten auf einen bestimmten Filter einschränkt, dann ist es in manchen Fällen wahrscheinlich, das man diese Menge weiter einschränken möchte. Deswegen kann es Sinn machen vorherige Ergebnisse zu Cachen. Obwohl ich jetzt eine const-Funktion aufrufe, verändere ich intern eine Datenstruktur, die die letzten x-Anfrage-Ergebnisse enthält.

    Also bei Optimierungen, die intern ein Caching verwalten.



  • @XSpille: Nein, sowas ist definitiv ein Fall für das mutable Keyword. Eine als const deklarierte Variable zu ent-consten erzeugt undefiniertes Verhalten 😉





  • 314159265358979_ schrieb:

    @XSpille: Nein, sowas ist definitiv ein Fall für das mutable Keyword. Eine als const deklarierte Variable zu ent-consten erzeugt undefiniertes Verhalten 😉

    Stimmt... Mutable hab ich völlig vergessen...
    Aber wenn ich eine std::map als member in meinem const-Objekt habe, dann ist der Member doch nicht automatisch auch const, oder?
    Die map selbst ist doch nicht-const. Also sollte es doch nicht undefiniert sein, oder?



  • XSpille schrieb:

    Aber wenn ich eine std::map als member in meinem const-Objekt habe, dann ist der Member doch nicht automatisch auch const, oder?

    Doch. Wenn *this const ist, sind auch alle Member const. (Es sei denn, sie sind als mutable deklariert)



  • 314159265358979_ schrieb:

    Gugelmoser schrieb:

    Hast du noch ein Beispiel?

    Wir nehmen an, die const-Version von baz() ist eine ziemlich lange Methode.

    struct foo
    {
        bar const& baz() const;
    
        bar& baz()
        {
            return const_cast<bar&>(static_cast<foo const*>(this)->baz());
        }
    };
    

    Andersherum kommst du mit einem const_cast aus:

    struct foo
    {
       foo& bar()
       {
          // viel Code
       }
    
       const foo& bar() const
       {
          return const_cast<foo*>( this )->bar();
       }
    }
    


  • DocShoe schrieb:

    314159265358979_ schrieb:

    Gugelmoser schrieb:

    Hast du noch ein Beispiel?

    Wir nehmen an, die const-Version von baz() ist eine ziemlich lange Methode.

    struct foo
    {
        bar const& baz() const;
    
        bar& baz()
        {
            return const_cast<bar&>(static_cast<foo const*>(this)->baz());
        }
    };
    

    Andersherum kommst du mit einem const_cast aus:

    struct foo
    {
       foo& bar()
       {
          // viel Code
       }
    
       const foo& bar() const
       {
          return const_cast<foo*>( this )->bar();
       }
    }
    

    Das wird nix. Kannst du garantieren, das die nicht-const Version von baz sich const verhält? Sonst darfst du sie ja nicht aus der const Version von baz aus aufrufen! Im Allgemeinen sollte das nicht der der sein, denn sonst bräuchtest du ja keine nicht-const Version :xmas1:



  • Ok, so langsam habe ich es. Es vielen Dank für die Antworten.

    Viele Grüsse,
    gallagher



  • bmario_ schrieb:

    Das wird nix. Kannst du garantieren, das die nicht-const Version von baz sich const verhält? Sonst darfst du sie ja nicht aus der const Version von baz aus aufrufen! Im Allgemeinen sollte das nicht der der sein, denn sonst bräuchtest du ja keine nicht-const Version :xmas1:

    😕



  • DocShoe schrieb:

    bmario_ schrieb:

    Das wird nix. Kannst du garantieren, das die nicht-const Version von baz sich const verhält? Sonst darfst du sie ja nicht aus der const Version von baz aus aufrufen! Im Allgemeinen sollte das nicht der der sein, denn sonst bräuchtest du ja keine nicht-const Version :xmas1:

    😕

    Ähm ja, war wohl zu kurz gefasst.

    Das man in einem nicht-const Objekt jede beliebige const Funktion aufrufen kann, sollte klar sein. Genauso klar ist es, dass du ohne Probleme aus nicht-const Funktionen const Funktionen aufrufen kannst und beim Rückgabewert etwaige const-ness wegcasten kannst. Das kannst du machen, da dein Objekt ohne nicht const ist und ein Benutzer deiner Klasse damit auch nicht erwartet, dass sich das Objekt const verhält.

    Anders herum ist es aber ein Problem. Hast du ein Objekt, dass const ist und du versuchst nun eine nicht const-Funktion zu benutzen (dank const cast auf this ohne Probleme möglich) hast du ein Problem, wenn diese nicht const Funktion etwas am Objekt verändert. Das ist ein Problem, da sich in diesem Fall aus Benutzersicht ein const Objekt, für das eine const Funktion aufgerufen wurde, ändert!

    Da du das Objekt selbst "ent-const-est" kannst du auch keinerlei Garantien darüber abgeben, ob die aufgerufene Funktion sich const verhält. Aber andersherum ist das egal. Du hast ein nicht-const Objekt und darfst damit alles machen was du willst, unter anderem Funktionen nutzen, die const sind.

    Hoffe das ist jetzt verständlicher, ansonsten mal bei Scott Meyers nachschlagen, der Mann kann definitiv besser erklären als ich.


Anmelden zum Antworten