Brauche Hilfe: Typkonvertierung (verschiedene Casts) Objekt File I/O



  • Hallo Leute,
    ich bräuchte eure kompetente Hilfe bezüglich der verschiedenen Arten von casts. Es geht eigentlich um binäre Dateiein und -ausgabe (von Objekten Marke Eigenbau). Die entsprechende Funktionen sind mir bekannt, ich habe sie aber verschieden implementiert gesehen. Nämlich:

    ofs.write((char*)&myStruct, sizeof(myStruct));
    ofs.write(static_cast<char*>&myStruct, sizeof(myStruct));
    ofs.write(reinterpret_cast<char*>&myStruct, sizeof(myStruct));

    Input (read) dann entsprechend.......

    Es scheint also so, dass alle 3 Varianten funktionieren würden. Für mich stellt sich jetzt die Frage wie ich es implementieren soll.

    Ich gestehe - habe keinen Tau was es mit den verschiedenen cast Arten auf sich hat! Wie unterscheiden sich die 3 Varianten (in welchen Punkten) ?
    Was macht static_cast anders als reinterpret_cast oder die stinknormale erste Variante ? Welche soll ich dann nehmen und vorallem WARUM 😕 ?

    Wäre echt dankbar für entsprechende hints

    Ciao,
    cpplumpi





  • es handelt sich nicht um ein ressourcenproblem (wo finde ich infos) sondern ein verständnisproblem ! ein link auf msdn hilft mir da leider nicht weiter ..... 😞



  • cpplumpi schrieb:

    es handelt sich nicht um ein ressourcenproblem (wo finde ich infos) sondern ein verständnisproblem ! ein link auf msdn hilft mir da leider nicht weiter ..... 😞

    Nun, das Verständnisproblem hätte mit der entsprechenden Ressource eigentlich gelöst werden können.

    Aber nochmal detaillierter:

    C-Cast, (B)a: du sagst dem Compiler "mach irgendwie aus der Variable von Typ A eine vom Typ B"
    static_cast<B>(a): "es gibt eine (nicht unbedingt implizite) Konvertierung von A nach B, wende sie an!" z.B. float --> int
    reinterpret_cast<B>(a): "nimm das Bitmuster von a und tu so als repräsentiere es eine Variable vom Typ B"

    In deinem Beispiel wird auf den meisten Plattformen der static_cast das selbe bewirken wie der reinterpret_cast, weil beide Pointertypen intern die selbe Darstellung haben. Beim C-Cast wird der Compiler zuerst entsprechend dem static_cast nach einer Konvertierungsmöglichkeit suchen (und in deinem Fall finden), wenns die nicht gibt (z.B. bei einer Konvertierung void* --> int oder ähnlichem) wird er wie reinterpret_cast das Bitmuster uminterpretieren.


  • Mod

    static_cast<char*>(&myStruct)
    

    Das ist unmöglich, es sei denn, myStruct ist selbst ein char (in diesem Falle wäre der Cast überflüssig), oder eine Klasse, deren überladener Adressoperator entweder eine Klasse mit Konvertierungsoperator nach char* oder void* oder (lvalue-)char-Array liefert.
    Als Faustregel kann man sich merken, dass static_cast diejenigen Konvertierungen unterstützt, die implizit möglich sind, sowie - bis auf ein paar Ausnahmen, wichtig vor allem das Weg-Casten von const - deren Umkehrungen.

    reinterpret_cast<char*>&myStruct
    

    Erzeugt einen Zeiger, der auf das erste Byte des Objektes myStruct zeigt (sofern der Adressoperator nicht wild überladen wurde). Die Problematik mit dem Adressoperator vermeidet man, wenn man Referenzcasts benutzt (die sind IMO ohnehin expressiver), also z.B.

    reinterpret_cast<char(&)[sizeof myStruct]>(myStruct)  // betrachte (=greife zu auf) myStruct, als ob es sich um ein Array aus chars handelt
    

    (Die Wirkung eines Refernzcasts, ist die gleiche wie die eines Zeigercasts, bei dem die Adresse gecastet wird und dann dereferenziert wird. Der wesentliche Punkt ist, dass hier immer der eingebaute Adressoperator genutzt wird - reinterpret_cast bewirkt niemals den Aufruf einer Funktion).

    (char*)&myStruct
    

    Sofern static-cast möglich ist, verhält es sich wie ein solcher, sonst - sofern möglich - wie ein reinterpret_cast. Weil gerade bei Casts in Zeiger häufig beide Formen möglich sind, ist die Bedeutung dieses Casts nicht immer auf Anhieb erkennbar: deshalb sollte er vermieden werden (abgesehen von der geringen Sichtbarkeit im Code).



  • 🙂

    jetzt blick ich, denke ich, auch durch! man kann sich ja doch auf euch verlassen ! scherz beiseite - vielen dank an euch alle, und besonders an jene die sich etwas mehr zeit genommen haben meine c++ wissenslücken zu stopfen....

    lg
    cpplumpi


Anmelden zum Antworten