Container mit abgeleiteten Klassen + delete



  • Ich möchte bzw. muss mehrere abgeleitete Klassen in einem gemeinsamen Container peichern(in einer Map).

    Die Objekte werden mir von einem virtuellen Konstruktor geliefert und alles was ich von dem
    Objekt kenne ist die Schnittstelle der Basisklasse.

    Wenn ich nun am Ende des Programmes den Speicher freigeben möchte funktioniert
    eine einfache Schleife mit delete map[i] ja nicht richtig,
    da hier die größe der Basisklasse angenommen wird.

    Das Interface bzw. die Basisklasse sieht so aus:

    class Base
    {
        public:
        Base ();
        virtual ~Base() = 0;
    
        //Hiermit werden alle abgeleiteten Klassen "gestartet"
        virtual run () = 0;
    };
    

    Diese Objekte erhalte ich über eine Funktion aus einer DLL, diese so aussehen könnte:

    Base *createInstance ()
    {
        return new Derived1;
    }
    

    Die entsprechende DLL kennt ja die größe des Objektes und könnte daher das Objekt auch löschen.

    Dafür wüsste ich spontan 2Ansätze, der eine wäre dieser:

    class Base
    {
        public:
        Base ();
        virtual ~Base() = 0;
    
        //Hiermit werden alle abgeleiteten Klassen "gestartet"
        virtual run () = 0;
    
        //Hiermit wird das Objekt gelöscht
        virtual delete () = 0;
    };
    

    delete() ein delete this; ausführen.

    Das ganze gefällt mir aber nicht so, aber es gibt ja noch den zweiten Ansatz:

    Ich schreibe in jeder DLL noch eine zweite Funktion deleteInstance, welche
    ein Übergebenes Objekt mit dynamic_cast in die abgeleitete Klasse castet und dieses mit delete löscht.

    Würde dann ca. so aussehen

    bool deleteInstance (Base& instance)
    {
        Derived1* obj = dynamic_cast<Derivec1 *>(instance);
        if (obj)
        {
            delete obj;
            return true;
        }
        return false;
    }
    

    Welche Methode würdet ihr den Vorzug geben und wenn ja weshalb?
    Würdet ihr weder das eine noch das andere Verwenden und wenn ja weshalb?

    Das ganze soll das Interface für nen Plug-In-System werden, wenn meine Idee also total mies ist, dann bitte Verbesserungsvorschläge 🙂

    Das ganze soll ca. so funktionieren:
    -Alle DLLs in einem Ordner X laden
    -Der Reihe nach die Map (map<string, Base*>) mit createInstance befüllen
    -Die Plug-Ins mit run() starten

    Edit:

    Was ich unbedingt noch erwähnen muss:
    Die Map dient dazu, dass die Plug-Ins auf andere Plug-Ins zugreifen können.
    Hier steh ich jedoch gerade vor dem Problem, dass ich eine Initialisierungsreihenfolge
    benötige, bei der ein Plug-In X welches A und B benötigt nach A und B initalisiert werden muss
    (ich denke ihr versteht was ich meine), wie kann ich das bei meinem System garantieren?
    Ich sehe nämlich genau da irgendwie ne Schwachstelle in dem ganzen, da es ab diesem
    Moment nicht mehr so sauber wirkt (habe ich jedenfalls das Gefühl).



  • Wenn ich nun am Ende des Programmes den Speicher freigeben möchte funktioniert
    eine einfache Schleife mit delete map[i] ja nicht richtig,
    da hier die größe der Basisklasse angenommen wird.

    quatsch. Aus dem Grund hat man ja virtuelle Destruktoren und vtables.

    Übrigens ist es zu empfehlen, die Speicherverwaltung zu automatisieren 🙄



  • Also kann man das problemlos schreiben?



  • Solange du das ganze nicht verallgemeinerst und den Vector dann mal eben polymorph verwendest, ja.



  • kingruedi schrieb:

    Wenn ich nun am Ende des Programmes den Speicher freigeben möchte funktioniert
    eine einfache Schleife mit delete map[i] ja nicht richtig,
    da hier die größe der Basisklasse angenommen wird.

    quatsch. Aus dem Grund hat man ja virtuelle Destruktoren und vtables.

    Übrigens ist es zu empfehlen, die Speicherverwaltung zu automatisieren 🙄

    Du hast doch "Mehr Effektiv C++" irgendwo rumliegen, da wird dieses Problem in Richtlinie 3 erwähnt,
    wieso trifft dieses Problem nicht auf meinen Fall zu?



  • SirLant schrieb:

    Du hast doch "Mehr Effektiv C++" irgendwo rumliegen, da wird dieses Problem in Richtlinie 3 erwähnt,
    wieso trifft dieses Problem nicht auf meinen Fall zu?

    😕
    Item drei von MEC++ trägt den Titel: "Never treat arrays polymorphically".
    Was soll das denn mit deiner Frage zu tun haben?
    Ich sehe hier keine Arrays (du schreibst von einer map). Außerdem hälst du deine Elemente by Pointer.


Anmelden zum Antworten