Virtuelle Klasse in Liste



  • Hi Community!

    Ich habe eine Oberklasse A, bei der ich ein paar Methoden rein virutell gemacht habe (virtual void met() = 0;) und andere definiert habe.
    Des Weiteren habe ich zwei Klassen B1 und B2 die von A erben. Dort werden auch die virtuellen Methoden überschrieben (und somit definiert).

    Jetzt möchte ich in einer Liste (list a) Instanzen der Objekte B1 und B2 speichern und anschließend die Methode met() aufrufen.
    Wenn ich

    list<A> a;
    

    mache, dann sagt g++:

    [...] error: cannot declare field `std::_List_node<GraphicObj>::_M_data' to be of type `A'
    [...]: error: because the following virtual functions are abstract:
    [...]

    Wie geht es also sonst? Wie kann ich B1 und B2 in eine Liste speichern? Oder müsste das so gehen und ich mach was anderes falsch?

    Danke für alle Anregungen.
    Konstantin



  • Musst Zeiger benutzen.

    list<A *> a;
    


  • OK, danke, und wie benutze ich dann push_back?

    a.push_back(b1)
    

    geht ja wohl nicht.

    Würd ja sagen:

    a.push_back(&b1)
    

    Ich versteh diese Pointerdinger einfach nicht. Könnt ihr mir kurz auf die Sprünge helfen?



  • Konstantin schrieb:

    a.push_back(&b1)
    

    Ich versteh diese Pointerdinger einfach nicht. Könnt ihr mir kurz auf die Sprünge helfen?

    Prinzipiell ist das richtig. funktioniert aber nur solange b1 nicht ungültig wird.
    normalerweise würde man sowas machen.

    a.push_back(new b( irgendwas ));
    

    Dann musst du natürlich die Objecte irgendwann wieder freigeben.
    Kurt

    EDIT: sehe gerade dein vektor ist eine membervariable. dann kannst du davon ausgehen dass du die elemente mit new anlegen musst. Fürs Freigeben bietet sich dann der dtor an.



  • Also, um das noch mal klarzustellen:

    public A
    {
       public:
       A()
       {}
    
       void abc()
       {
          // hier tu ich was
       }
    
       void met()=0;
    };
    
    public B1 : public A
    {
       public:
       B1()
       {
       }
    
       void met()
       {
          // hier passiert was
       }
    };
    
    public B2 : public A
    {
       public:
       B1()
       {
       }
    
       void met()
       {
          // hier passiert was
       }
    };
    

    In der main:

    list<A*> a;
    B1 b1();
    B2 b2();
    

    Wie füge ich jetzt b1 und b2 zu der Liste hinzu, so dass ich hinterher für jedes Objekt in der Liste .met() ausführen kann?



  • list<A*> a;
    a.push_back(new B1);
    a.push_back(new B2);
    for( list<A*>::iterator i = a.begin(); i != a.end(); ++i )
       (*i)->met();
    for( list<A*>::iterator i = a.begin(); i != a.end(); ++i )
       delete (*i);
    

    Kurt



  • Oh ja ... es funktioniert. Ich hatte noch nen Fehler in einer anderen Zeile. Hatte da die Zeilen verwechselt.

    Danke dir.



  • Und nicht vergessen, den Dtor der Basis-Klasse dann virtual zu machen.



  • C Newbie schrieb:

    Und nicht vergessen, den Dtor der Basis-Klasse dann virtual zu machen.

    Den was? Was muss ich machen?



  • hi,

    du musst den Destruktor der Basisklasse virtual machen, damit die Destruktoren der abgeleiteten Klassen aufgerufen werden.


Anmelden zum Antworten