casts



  • Hi,
    😕 Was is denn der Unterschied zwischen static_cast<> und dynamic_cast<> genau?



  • von hume aus der faq:

    static_cast benutzt man, wenn man schon zur Compilezeit weiß, von welchem Typ ein zu castender Typ ist.
    dynamic_cast ist ein Laufzeitcast. Du benutzt diesen, um in einer Klassenhierarchie "nach unten" zu casten. Also wenn du ein Pointer vom Typ Basisklasse hast hinter dem sich aber ein Objekt einer abgeleiteten Klasse befindet, solltest du mit dem dynamic_cast arbeiten.

    da steht glaub ich auch noch was zu den anderen casts ...



  • static_cast :

    In allen Fällen, in denen ein vollständiger Typ mit den sonstigen herkömmlichen Mitteln der Programmiersprache in einen anderen Typ umgewandelt werden kann, führt die Umwandlung mit dem Operator static_cast exakt zum selben Ergebnis.

    Ganzzahltypen können in Aufzählungstypen umgewandelt werden. Der Versuch, arg in einen Wert umzuwandeln, der keiner der Aufzählungskonstanten entspricht, liefert ein undefiniertes Ergebnis.

    dynamic_Cast :

    In dem Ausdruck dynamic_cast< T > (ptr) muß T ein Zeiger oder eine Referenz auf einen definierten Klassentyp oder auf void sein. Das Argument ptr muß ein Ausdruck sein, dessen Auswertung einen Zeiger oder eine Referenz ergibt.

    Wenn T ein Zeiger auf void ist, muß ptr ebenfalls ein Zeiger sein. In diesem Fall kann man über den Zeiger auf jedes Element derjenigen Klasse zugreifen, die in der Klassenhierarchie die unterste ist. Eine solche Klasse kann nicht Basisklasse irgendeiner anderen Klasse sein.

    Die Umwandlung von einer abgeleiteten Klasse in eine Basisklasse oder in eine andere abgeleitete Klasse geschieht wie folgt: Wenn T ein Zeiger ist und ptr ein Zeiger auf eine Nicht-Basisklasse, die ein Element einer Klassenhierarchie ist, so ist das Ergebnis ein Zeiger auf die eindeutige Unterklasse. Referenzen werden ähnlich behandelt. Wenn T eine Referenz ist und ptr eine Referenz auf eine Nicht-Basisklasse, so ist das Ergebnis eine Referenz auf die eindeutige Unterklasse.

    Eine Umwandlung von einer Basisklasse in eine abgeleiteten Klasse ist nur möglich, wenn die Basisklasse von polymorphem Typ ist.

    🙄 🙄



  • Wenn T ein Zeiger auf void ist, muß ptr ebenfalls ein Zeiger sein. In diesem Fall kann man über den Zeiger auf jedes Element derjenigen Klasse zugreifen, die in der Klassenhierarchie die unterste ist. Eine solche Klasse kann nicht Basisklasse irgendeiner anderen Klasse sein.

    😕 Den Satz verstehe ich nicht.

    Ein dynamic_cast nach void* liefert einen Zeiger auf das am weitesten abgeleitete Objekt auf das ptr zeigt. Und damit letztlich die Startadresse des Objekts auf das ptr zeigt. Was sagt der obere Satz?

    Was den static_cast angeht, sollte man sich merken, dass dieser immer dann angewendet werden kann, wenn es sich bei dem cast um das Inverse einer impliziten Standardkonvertierung handelt.
    Wenn ich also von S nach T casten will, dann muss es eine implizite Konvertierung von T nach S geben.



  • hab ich aus der borland hilfe hierzu noch dieses bsp

    // WIE MAN MIT DYNAMISCHEN TYPUMWANDLUNGEN (DYNAMIC_CAST) ARBEITET.
    // Dieses Programm muß mit der Option -RT (RTTI erzeugen) compiliert
     werden.
    #include <iostream>
    #include <typeinfo.h>
    
    class Basis1
    {
       // Damit der RTTI-Mechanismus korrekt funktioniert,
       // muß die Basisklasse polymorph sein.
       virtual void f(void) { /* Eine virtuelle Funktion macht die Klasse
     polymorph. */ }
    };
    
    class Basis2 { };
    class Abgeleitet : public Basis1, public Basis2 { };
    
    int main(void) {
       try {
          Abgeleitet d, *pd;
          Basis1 *b1 = &d;
    
          // Objekt Basis1 nach Abgeleitet umwandeln.
          if ((pd = dynamic_cast<Abgeleitet *>(b1)) != 0) {
               std::cout << "The resulting pointer is of type "
                    << typeid(pd).name() << std::endl;
             }
          else throw Bad_cast();
    
          // Eine Typumwandlung quer durch die Hierarchie versuchen, in
          // diesem Fall eine Umwandlung von der ersten Basisklasse zur
    
          // untersten abgeleiteten Klasse und dann zurück zu einer
        // anderen Basisklasse
          Basis2 *b2;
          if ((b2 = dynamic_cast<Basis2 *>(b1)) != 0) {
              cout << "Der sich ergebende Zeiger hat den Typ "
                   << typeid(b2).name() << endl;
             }
          else throw Bad_cast();
          }
       catch (Bad_cast) {
          cout << "dynamic_cast hat versagt" << endl;
          return 1;
          }
       catch (...) {
          cout << "Fehler bei der Exception-Behandlung." << endl;
    
          return 1;
          }
    
       return 0;
    }
    


  • @1ntrud0r
    Die Prinzipien des dynamic_casts sind mir durchaus bekannt. Mein Problem liegt eher in der Formulierung des zitierten Satzes.

    Wenn T ein Zeiger auf void ist, muß ptr ebenfalls ein Zeiger sein

    Jo. Ist klar.

    In diesem Fall kann man über den Zeiger auf jedes Element derjenigen Klasse zugreifen, die in der Klassenhierarchie die unterste ist

    Wer ist "den Zeiger"? Ich gehe mal davon aus, dass es sich hier um den aus dem cast resultierenden Zeiger handelt. Dieser hat den Typ void*. Damit kann ich also auf garnix zugreifen.

    Eine solche Klasse kann nicht Basisklasse irgendeiner anderen Klasse sein.

    Dieser Satz beinhaltet keine Information. Das die unterste Klasse einer Hierarchie nicht Basisklasse sein kann, wird bereits durch die Worte "die unterste" festgelegt.

    Dein Beispiel hilft mir übrigens gar nicht weiter, da dort vieles, aber kein cast nach void* zu sehen ist.



  • Danke...


Anmelden zum Antworten