Vererbungsproblem mit Stack



  • Bevor noch irgendwelche Katastrophen passieren, möchte ich an dieser Stelle erwähnen, dass du bei zukünftlichen Postings bitte das Syntax Highlighting benutzen sollst, somit wird dein Code farbig markiert und somit übersichtlicher und lesbarer. Einfach das nächste mal den kompletten Code markieren, und auf die untere Schaltfläche "C/C++" klicken 😉

    MfG mikey.



  • Ok dann mit den highlighting werde ich mir zu Herzen nehmen 😉

    Verstehe aber trotzdem nicht ganz wie ich das über virtuelle Funktionen lösen kann.
    Bitte um einen kleinen Denkanstoß 😉

    Danke!
    mfg,
    shed



  • #include <stack>
    #include <iostream>
    
    class Base
    {
    public:
        virtual void Booyakah () {}
    
        virtual ~Base () {} // virtueller Destruktor, immer hinzufügen, wenn
                            // die Klasse Basisklasse sein soll und virtuelle Funktionen enthält
    };
    
    class Derived1 : public Base
    {
    public:
        virtual void Booyakah ()
        {
            std::cout << "Booyakah!" << std::endl;
        }
    };
    
    class Derived2 : public Base
    {
    public:
         virtual void Booyakah ()
         {
             std::cout << "bOOYAKAH1" << std::endl;
         }
    };
    
    int main ()
    {
         std::stack<Base*> s;
         s.push (new Derived1);
         s.push (new Derived2);
         Base* p = s.top ();
         s.pop ();
         p->Booyakah ();
         delete p;
         p = s.top ();
         s.pop ();
         p->Booyakah ();
         delete p;
    }
    


  • Das funktioniert ja aber nur bei Methoden oder? Mein Problem ist, dass ich die Attribute die die Subklassen zusätzlich haben nicht mitgespeichert werden.
    zB

    class Base
    {
      public:
        int attrBase;
    }
    
    class Derived1 : public Base
    {
      public:
       int attrDerived1;
    }
    
    class Derived2 : public Base
    {
      public:
       int attrDerived2;
    } 
    
    int main()
    {
      static std::stack<Base*> myStack; 
      Derived1 myDerived1;
      myStack.push(myDerived1);
    }
    

    Mein Problem ist also, dass wenn ich eine Subklasse in den Stack schreibe dann habe ich nur das Attribute 'attrBase' nicht aber "attrDerived1". Dies kann ich ja durch virtual nicht lösen oder? 😕

    Danke!



  • ich hab mal eine frage hierzu:

    Base* p = s.top ();
    s.pop ();
    p->Booyakah ();
    

    p zeigt doch auf das oberste element aus s oder?
    bei s.top(), wird da nicht auch p ungültig?



  • Ich kann dich beruhigen: Die Attribute werden mitgespeichert - nur weiß ein Base* Zeiger nichts von ihrer Existenz. Das heißt, du mußt entweder in der Basisklasse virtuelle Getter bereitstellen (und in der abgeleiteten Klasse entsprechend anpassen) oder du nutzt dynamic_cast<> (auch wenn das ein sicheres Zeichen für schlechtes Design ist ;)).

    @sadsadsadsa (sehr einfallsreicher Name :D):
    s.pop() entfernt nur das oberste Element (der Zeiger) aus dem Stack - die Daten hinter dem Zeiger werden dabei nicht angefasst. Das Objekt selbst überlebt so lange, bis du es per delete vernichtest.



  • shed schrieb:

    ...
    In diesen stack will ich nur Y und Z Objekte schreiben...

    Warum ? 😃
    Ich bin immer sehr skeptisch, wenn jemand in einen Container "wirklich unterschiedliche" Sachen reintun will. Eigentlich fallen mir nur 3 Gründe für sowas ein:

    • Entweder "packt" man sie doch nur aufgrund einheitlicher Eigenschaften (die dann auch der Basisklasse bekannt sind),
    • Oder man wird durch "harte technische Fakten" zu dieser Bedienung einer Schnittstelle gezwungen ("weiß nicht, wie's besser geht" zählt da nicht 😉 )
    • Oder man hat sich tatsächlich das Problem noch nicht sauber durchdacht.

    Mal eine Frage: Wie heißt Dein Stack fachlich ? "Y_oder_Z_Objekte_Oder_sonstiges" ? 😉

    Also nochmal mein Tipp: Gemeinsamem Eigenschaften identifizieren, in eine Basisklasse auslagern (per virtual) und Laufzeitpolymorphie nutzen (=> .filmor).

    Ach ja:

    shed schrieb:

    ...

    ...
      static std::stack<Base*> myStack; 
      Derived1 myDerived1;
      myStack.push(myDerived1);
    }
    

    ...

    Hier fehlt noch ein Adressoperator:

    ...
      myStack.push(&myDerived1);
    }
    

    Gruß,

    Simon2.



  • Ah, beim Adressoperator hab ich mich nur vertippt 😉

    Naja dann werde ich mir das Problem noch einmal durchdenken. Vielleicht is es ja wirklich besser, nicht beides in den gleichen Container zu packen.

    Vielen Dank für die Tipps! 🙂 (ich hab bis jetzt nur java programmiert, merkt man wahrscheinlich an meinen posts 😉 )

    mfg,
    shed



  • Das hier

    ...
      static std::stack<Base*> myStack;
      Derived1 myDerived1;
      myStack.push(&myDerived1);
    }
    

    halte ich für keine gute Idee. Du hättest hier nach der schließenden Klammer lauter ungültige Objekte in deinem Stack, da du Pointer auf lokale Objekte speicherst. Mach es liebe wie .filmor.



  • Hab das Problem lösen können Danke! Und ich hab jetzt für jeden Typ einen eigenen Stack 😉

    Danke nochmal!



  • Braunstein schrieb:

    Das hier

    ...
      static std::stack<Base*> myStack;
      Derived1 myDerived1;
      myStack.push(&myDerived1);
    }
    

    halte ich für keine gute Idee....

    Huuups - hast natürlich Recht !
    (Hatte gar nicht gesehen, dass er den Scope wieder verlässt).

    shed schrieb:

    Hab das Problem lösen können Danke! Und ich hab jetzt für jeden Typ einen eigenen Stack 😉 ...

    Sehr gut ! 👍 😋 😃

    Gruß,

    Simon2.


Anmelden zum Antworten