Iterator upcast?



  • Von einer normalen Basis Klasse leite ich eine Template Klasse ab:

    Da ich keine std::list der Template Klasse machen kann (außer sie ist nur auf einen Typ beschränkt) erstelle ich eine leere Base Klasse.
    Nun kann ich eine std::list<Base*> erstellen und den Template Klassen Konstruktor so schreiben, daß er die Klasse automatisch zur Liste hinzufügt.

    class Base
    {};
    
    template<typename T>
    class Derived : public Base
    {
        public:
            Derived();
        private:
            std::string name;
    };
    

    Nun möchte ich die Derived Klassen alphabetisch sortiert in die Liste einfügen, kann aber mit dem Iterator nicht auf die Membervariable "name" von Derived zugreifen.
    Ich gehe folgendermaßen vor:

    // Im Derived Konstruktor:
    std::list<Base*>::iterator it;
    for (it = base_list.begin(); it != base_list.end(); it++)
    {
        if (this->name.compare((*it)->name) > 0)   // (*it)->name geht nicht!
            break;
    }
    base_list.insert(it, this);
    

    Ich habe schon probiert den iterator mit static_cast zu casten, das hat aber nix gebracht (oder ich habe es falsch gemacht).

    Weiß jemand weiter?



  • it ist ein iterator für eine liste von Zeigern auf Base, nicht auf Derived. Base hat aber kein element namens "name".
    entweder, du verwendest eine list<Derived*> und ihren iterator, oder - wenn du dir sicher bist, dass alle Base* auf ein Derived-Objekt zeigen, machst du:

    static_cast<Derived*>(*it)->name
    


  • Um von der Basisklasse auf deren abgeleitete zu casten, nimmt man eigentlich dynamic_cast.



  • deshalb hab ich auch geschrieben "wenn du sicher bist, dass ...".
    und so wie er die zeiger verwendet, sieht das ziemlich sicher aus.
    deshalb hab ich ihm auch dazu geraten, eine std::list<Derived*> zu verwenden.
    Aber klar: wenn list<Base*> auch anderes enthalten kann, dann

    Derived *d = dynamic_cast<Derived*>(*it);
    if (d) {
        //was auch immer
    }
    

Anmelden zum Antworten