std::list, std::vector - Umgang mit Referenzen



  • Hallo liebe C++ Community,
    während der Arbeit an einem kleinen Projekt von mir bin ich auf folgendes Problem gestoßen:

    Es existiert eine abstrakte Basisklasse "basis" mit einer rein virtuelle Methode

    class basis {
    
    public:
      void foo() = 0;
    
    };
    

    Von dieser Klasse werden mehrere andere Klassen mittels public-Vererbung abgeleitet.

    class abgeleitet: public basis {
    
    public:
      void foo() {
        // sommething to do
      }
    
    }
    

    Es gibt nun mehrere verschiedene abgeleitete Klassen. Nun muss ich diese in einer Liste/Array/o.Ä. speichern. Da die Typerkennung erst zur Laufzeit erfolgen kann habe ich mir überlegt die Instanzen der abgeleiteten Klassen als Referenz in einem Vector zu speichern.

    #include <vector>
    
    ...
    
    std::vector<basis&> vSpeicher;
    

    Dabei erhalte ich jedoch immer Compilerfehlmeldungen

    Microsoft Visual C++ 2008 Express Edition:
    1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\xmemory(95) : error C2528: 'pointer': Zeiger auf Verweis ungültig

    Können die Containerklassen std::list und std::vector der STL nicht mit Referenzen umgehen oder liegt das nur daran das die Basisklasse abstrakt ist? Beziehungsweise gibt es eine andere möglichkeit die abgeleiteten Klassen zu speichern?

    Mit freundlichen Grüßen
    Stefan



  • Du kannst keine Referenzen in Container verwenden, da die Elemente kopiert und zugewiesen werden (und im Weiteren Objekte sein müssen). Nimm stattdessen Zeiger.



  • Und dann nimm auch Container, die für Zeiger gedacht sind, etwa die aus boost::ptr_container



  • Gute Idee. Oder um etwas flexibler zu sein, kann man auch boost::shared_ptr in Standardcontainern verwenden.


  • Administrator

    Sind diese Empfehlungen nicht leicht übertrieben? Ich habe auch schon Zeiger gespeichert und wollte kein Ownership übertragen. Und gleich einen boost::shared_ptr mit Referenzzählung? Zuerst sollte man wohl mehr über das Problem an sich erfahren, bevor man die Vorschlaghämmer empfiehlt 😉

    Grüssli



  • Dravere schrieb:

    Sind diese Empfehlungen nicht leicht übertrieben? Ich habe auch schon Zeiger gespeichert und wollte kein Ownership übertragen.

    In vielen Fällen benutzt man Container aber, um Objekte darin zu speichern. Da mit reinen Objekten keine Polymorphie funktioniert, nimmt man Zeiger. Und damit man sich nicht um deren Freigabe kümmern muss, nimmt man Smart Pointer oder Pointer Container.

    Wenn es nur darum geht, nicht-besitzende Verweise in Containern zu halten, hast du Recht. Aber mir scheint das hier nicht der Fall zu sein...



  • danke für die vielen Antworten.

    Ich werde es mal mit de Smart Pointern aus der boost Bibliothek versuchen



  • Wenn du die Flexibilität von shared_ptr nicht brauchst (problemloses Verschieben und Besitz-Teilen), sind Pointer-Container wohl die bessere Wahl, da du dort weniger Overhead (z.B. durch wegfallende Referenzzählung) hast und deine Datenstruktur dadurch womöglich ein wenig schneller ist.



  • ... nimmt man Zeiger. Und damit man sich nicht um deren Freigabe kümmern muss, nimmt man ...

    Ich dachte immer, dann nimmt man Java. 🙂


Anmelden zum Antworten