Was passiert hier genau ? (Typumwandlung Basisklasse -> Ableitung)



  • #include <iostream>
    using namespace std;
    
    struct Elem
    {
    	Elem * next;
    
    };
    
    struct Zahl: public Elem
    {
    	int Wert;
    };
    
    int main()
    {
    	Zahl z;
    	z.Wert = 10;
    
    	Elem *e = &z;			//Zeiger auf ein Element(speziell eine Zahl)
    
    	Zahl *z2 = (Zahl*) e;	//<-???
    
    	cout<< z2->Wert;
    
    }
    

    Hallo.
    Kann mir einer sagen was in der Zeile

    Zahl *z2 = (Zahl*) e;	//<-???
    

    genau passiert ?

    Der Abgeleiteten Klasse (bzw. dem Pointer auf sie) wird hier doch ein Pointer auf ein Objekt der Basisklasse zugewiesen. Allerdings habe ich keinen Zuweisungsoperator überladen. Was geschieht denn da genau ?



  • trollalarm -.-



  • trollalarm schrieb:

    trollalarm -.-

    Und was bist du dann? 🙄

    @bauglir:
    Wenn du selber keinen Zuweisungs-Operator schreibst, erstellt dir der Compiler einen.
    Und diese Codezeile castet e in einen Zahl* und weißt ihn z2 zu.



  • jo der postet in vb foren und forum-hilfe.de usw... omg



  • Hallo

    so etwas in die richtung habe ich mir gedacht.

    Was ich allerdings noch nicht ganz verstehe :

    Am Anfang habe ich ja diese Zahl z mit dem Wert 10.
    Dann wird dem Pointer *e vom Typ Elem diese Zahl zugewiesen. Soweit denke ich kein Problem, denn "Zahl ist ein Elem" dachte ich mir.

    Wird dadurch das Elem automatisch zur Zahl ? Denn der Wert der in z steht geht ja nicht verloren, und ich kann auf ihn zugreifen, wenn ich *e wieder zurück zum Typ Zahl caste.



  • bauglir schrieb:

    Wird dadurch das Elem automatisch zur Zahl ? Denn der Wert der in z steht geht ja nicht verloren, und ich kann auf ihn zugreifen, wenn ich *e wieder zurück zum Typ Zahl caste.

    Das ist das Problem an C-Casts in C++, das funktioniert nur, wenn e tatsächlich auf ein Zahl-Objekt zeigt. Wenn es einen anderen Typ hat (z.B. eine auch von Elem abgeleitete Klasse "Buchstabe"), erhälst Du undefiniertes Verhalten.

    Als Lösung dafür gibt's den dynamic_cast, der 0 zurückliefert, wenn e auf etwas anderes als ein Zahl-Objekt zeigt, oder entsprechend eine bad_cast Exception wirft, wenn Du Referenzen castest.

    Elem* e = new Zahl;
    Zahl* z = dynamic_cast<Zahl*>(e);
    if (z != 0) {
      ...
    }
    

    Allerdings sollte man dynamic_cast meiden, wenn es andere Techniken gibt, um das gewünschte zu erreichen. Und die gibt es fast immer.


  • Mod

    LordJaxom schrieb:

    Als Lösung dafür gibt's den dynamic_cast, der 0 zurückliefert, wenn e auf etwas anderes als ein Zahl-Objekt zeigt, oder entsprechend eine bad_cast Exception wirft, wenn Du Referenzen castest.

    Elem* e = new Zahl;
    Zahl* z = dynamic_cast<Zahl*>(e);
    if (z != 0) {
      ...
    }
    

    Hier aber nicht, da Zahl kein polymorpher Typ ist.


Anmelden zum Antworten