Vererbungshierachie und CArray -> Problem



  • Folgende Vererbungs hierachie:

    class A {
    
    }
    
    class B : public A{
    
    }
    class C : public A{
    
    }
    

    Dann Array:

    CArray<A,A> Array;
    
    Array.Add(C);
    

    Dann Problem in folgenderZeile:

    C *pPointer = &(Array.ElementAt(0));
    

    FEHLER: C2440: A kann nicht in C konvertiert werden........

    jemand ne lösung??


  • Administrator

    C* Cptr = dynamic_cast<C*>(&Array.ElementAt(0));
    

    Aber ich würde mit dem Pointer vorsichtig umgehen, da er nicht immer auf dieses Objekt zeigen wird. Wieso verwendest du nicht zum Beispiel die Referenz und gleich GetAt?

    Grüssli



  • C *pPointer = (C*)&(Array.ElementAt(0));



  • wie meinst du das? Dravere.. wie würde es besser gehen?

    du meisnt so;

    C o= (C)(&Array.ElementAt(0));
    

    wo rin liegt der unterschied beim casten zwischen:

    dynamic_cast<C*> und (C*)


  • Administrator

    Tut mir leid, hab nen kleinen Fehler gemacht. Bin heute nicht so ganz auf der Höhe scheint mir ^^
    Ich hätte nämlich zuerst mal genauer anschauen sollen was du da schreibst, dann hätte ich gemerkt, dass das was du vor hast sowieso gar nicht geht. Also nochmals von vorne ^^

    CArray<A> Array; // Gleich wie CArray<A, A&>
    Array.Add(C); // Fügt nur ein A in das Array und zwar den A-Teil von C. Der Rest geht dabei verloren.
    
    C* pC = Array.GetAt(0); // Nimm GetAt, anstatt ElementAt! Und das geht logischerweise nicht.
    // Du hast schliesslich ein A Objekt im Array. Der C-Teil ging verloren. Das wäre fatal, wenn man es einfach so konvertiert.
    

    Das dynamic_cast hilft dir eben genau dabei. Dynamic_cast überprüft zur Laufzeit ob ein Objekt, wirklich in den anderen übergeführt werden kann. Also ob dieses A wirklich mal ein C war. Doch das A war nie ein C und er würde dir nen Null-Pointer zurückliefern. Das (C*) ist einfach die konvertierung aus C Zeiten und völlig ungesichert. In C++ sollte man die dynamic_cast, reinterpret_cast, static_cast und const_cast verwenden, welche gewisse unterschiedliche Sicherungen mit sich bringen.

    Wie kannst du dein Problem nun lösen? Tjo, du könntest zum Beispiel deine C's selber auf dem Heap anlegen. Die Pointer an ein CTypedPtrArray<CPtrArray, A*> und dann mit dynamic_cast wieder rausholen.

    C* pC = NULL;
    CTypedPtrArray<CPtrArray, A*> PtrArray;
    
    PtrArray.Add(new C());
    
    pC = dynamic_cast<C*>(PtrArray.GetAt(0));
    
    if(!pC)
    {
        // Wenn er hier rein geht, dann ist der Pointer NULL und somit war der Zeiger ursprünglich kein Zeiger auf ein C Objekt.
    }
    
    // Aufräumen natürlich nicht vergessen.
    while(PtrArray.GetCount() > 0)
    {
        delete PtrArray.GetAt(0);
        PtrArray.RemoveAt(0);
    }
    

    Ich hoffe das hat dir nun weitergeholfen ^^

    Grüssli



  • hmm.. ok hört sich schon mal gut an:)

    In deiner Lösung arbeitets du ja ,so wie ich das auf den ersten Blick sehe, mit einem Pointer array statt mit einem Objekt Array! gibt es keine anderen lösung? wäre sonst ne extremem aufwand den gesamten code umzumodeln!!

    Damals hatte ich quase nur die "class A" und alle Paramter und eigenschaften in dieser, klasse und so nur die verwenden die ich bruache, und wollte die nun bischen geordnet und eleganter in abgeleitet klassen trennen!!


  • Administrator

    Naja gibt natürlich auch die Frage, ob du abgeleitete Klassen überhaupt erstellen musst. Oder auch es gibt die Lösung, mehrere CArray's zu machen. Die Sache ist nun mal halt, dass in deiner Lösung, du die Objekte von der C-Klasse in eine A-Klasse kopierst. Also wird wenn man so will ein neues A-Objekt angelegt und den A-Teil des C-Objektes hineinkopiert. Der Rest geht dabei natürlich verloren.

    Ne Speicherung als A trotzdem es ein C ist und man es später wieder als C haben will, geht soweit ich das weiss nur über Referenzen und Pointern. Dabei wird der Speicher eben nicht verändert, sondern nur anderst drauf zugegriffen, bzw. man kommt beim A* nicht über den A-Teil des C-Objektes hinaus und somit bleibt das Objekt im Hintergrund immer noch ein C-Objekt, obwohl wir einen A-Pointer haben ^^

    Versteht man das überhaupt, was ich da rede? 😃

    Grüssli



  • hey Dravere,
    Jepp versteht man sehr gut:)
    Ich hab mich gestern doch nen halben tag hingesetzt und das mit deinen Pointer Array gemacht, und es funktioniert bisher hervorragend;)

    Allerdings musste ich st dynamic_cast , static_cast verwenden...

    Danke nochmal:)


Log in to reply