Vererbung: Zu welcher Unterklasse gehört die Instanz nun?



  • Guten abend

    man stelle sich folgenden einfachen aufbau vor:

    class Base {
    ...
    };
    
    class Sub1 : public Base {
    ...
    };
    
    class  Sub2 : public Base {
    ...
    }
    
    int main() {
     Base *instane;
    
     instance[0] = Sub1(..);
     instance[1] = Sub2(..);
     instance[3] = Sub2(..);
     instance[4] = Sub1(..);
     instance[5] = Base(...);
     usw..
    
    }
    

    an einer anderen Stelle im code muss ich dann wissen von welchem typ instance[i] ist. Was wäre die beste lösung für dieses problem?

    Ich könnte eigentlich eine virtuelle methode implementieren anhand deren rückgabewert man den typ identifizieren könnte, das scheint mir aber nicht sehr elegant.



  • So, wie du das im Moment machst, sind alle Instanzen vom Typ "Base" - das nennt sich Slicing 😉

    Ansonsten: Wenn du dein Programm so umstellst, daß es mit Zeigern arbeitet, dann kannst du mit RTTI oder dynamic_cast<> arbeiten. Aber normalerweise zeugt schon die Frage von schlechtem Design.



  • @bctac:
    Guck dir mal das Visitor Pattern an.



  • Da die Unterklassen meistens größer sind als die Basisklasse, können sie nicht einfach so direkt in dein Array (das du übrigens noch allozieren musst) kopiert werden. Daher benutzt man da eigentlich Pointer drauf (also Base **instance oder std::vector<Base *> oder std::vector<std::auto_ptr<Base> >). Demnach werden sie hier automatisch zu Base konvertiert.



  • wxSkip schrieb:

    std::vector<std::auto_ptr<Base> >

    Afaik wird das sich nicht compilieren lassen, weil die Kopieroperationen von auto_ptr nicht kompatibel zu den Anforderungen des Containers sind.



  • CStoll schrieb:

    wxSkip schrieb:

    std::vector<std::auto_ptr<Base> >

    Afaik wird das sich nicht compilieren lassen, weil die Kopieroperationen von auto_ptr nicht kompatibel zu den Anforderungen des Containers sind.

    Och schade. Und ich dachte schon, da würde sogar etwas mit dem aktuellen Standard gehen...



  • Nein, im aktuellen Standard gab's das noch nicht, die Lücke füllen eventuell std::vectorboost::shared\_ptr oder boost::ptr_vector<> (oder Äquivalente aus std::tr1). Es wird schon einen Grund haben, warum auto_ptr<> in C++0x als deprecated eingestuft wurde 😉



  • Man kann ja einfach einen std::vector<Base*> machen und dann die Speicherverwaltung mit einem selbstgeschriebenen Allokator machen.



  • wxSkip schrieb:

    Och schade. Und ich dachte schon, da würde sogar etwas mit dem aktuellen Standard gehen...

    std::unique_ptr , allerdings hat man dann nur Move-Semantik.

    EOutOfResources schrieb:

    Man kann ja einfach einen std::vector<Base*> machen und dann die Speicherverwaltung mit einem selbstgeschriebenen Allokator machen.

    Allokator selbst schreiben halte ich für Overkill. Zudem muss man die besitzenden Zeiger immer noch manuell freigeben.



  • Nexus schrieb:

    wxSkip schrieb:

    Och schade. Und ich dachte schon, da würde sogar etwas mit dem aktuellen Standard gehen...

    std::unique_ptr , allerdings hat man dann nur Move-Semantik.

    Ist (nocht) nicht der aktuelle Standard. Es sei denn ich hab ein Jahr verpennt 😉



  • Stimmt, hab irgendwie falsch gelesen 🙂


Anmelden zum Antworten