Gültigkeitsbereiche



  • Danke schön!

    Kann dann das abgelegte Objekt geändert werden, wenn man es aus dem vector holt? Denke schon, oder?

    Eine letzte Frage noch: Gibt es denn dann Möglichkeiten, Objekte und Variablen über Methoden- und Klassengrenzen hinweg zu verwenden, ohne sie immer alle zu übergeben, ohne sie alle global zu machen und ohne new zu verwenden?

    Kenne zumindest keine.
    Mein Problem mit new und delete ist, dass ich wenn ich Objekte dynamisch erzeuge ja nicht weiss, wie viele es sind wenn new und delete an unterschiedlichen Stellen ausgeführt werden müssen.
    Noch schlimmer wird es, wenn Zeiger auf Objekte an unterschiedlichen Stellen eingetragen werden und dann u.U. versucht wird ein Objekt 2 Mal mit delete freizugeben.

    Gibts da ne gute Vorgehensweise?

    Konkret hab ich ne Klasse, in deren init-Methode ich eine Reihe von Objekten anlege, die in dieser Klasse und in anderen Klassen verwendet werden. Zeiger darauf werden in einen vector eingetragen. Die Objekte werden mit new angelegt.
    Aber wo gebe ich sie wie wieder frei? Wenn sie nur in diesem einen vector stehen ist es kein Problem: Ich durchlaufe ihn und mache ein delete mit jedem Objekt im vector. Aber wenn ich sie in untersch. vector-Objekte lege, dann bekomme ich Probleme, wenn ich den delete mit jedem dieser vector-Objekte wie eben beschrieben mache.

    Ciao



  • Hi!

    Du könntest Statische Variablen verwenden. Was mir nicht ganz klar ist, ist was du mit "immer übergeben" meinst.

    Das Problem mit dem mehrfachfreigeben von Speicher kannst du mit Shared Pointern und Referenzenzählung lösen.
    Auch ein Thema in das du dich mal einlesen solltest: Smart Pointer.

    Dieser Lösungsansatz hilft dir auch bei der Problemlösung deiner letzten Frage!

    grüße



  • David_pb schrieb:

    Hi!

    Du könntest Statische Variablen verwenden. Was mir nicht ganz klar ist, ist was du mit "immer übergeben" meinst.

    An andere Klassen, Methoden usw.

    Das Problem mit dem mehrfachfreigeben von Speicher kannst du mit Shared Pointern und Referenzenzählung lösen.
    Auch ein Thema in das du dich mal einlesen solltest: Smart Pointer.

    Dieser Lösungsansatz hilft dir auch bei der Problemlösung deiner letzten Frage!

    grüße

    Das muss ich mir dann wohl auch mal antun! Gibt es noch nen anderen Ansatz, um mit new und delete ordentlich umzugehen?

    Danke!

    Ciao



  • Hi!

    Es gibt mehrere Vorgehensweisen. Aber wenn du wissen willst wieviel Zeiger auf einen Speicherbereich zeigen kommst du kaum um einen Refcounter rum.
    Das schöne an Smartpointern ist ja, das der Speicher automatisch freigegeben wird und du dich um nichtsmehr kümmern musst.
    Die Speicherfreigabe geschieht auch im falle von Ausnahmen:

    try
    {
       smartpointer< aufdeinobjekt > ptr( new deinobjekt );
       irgendeinfehlerwirdgeschmissen
    }
    catch( ... )
    {
      //
    }
    
    // Normal wär der Speicher hier verloren...
    

    grüße



  • David_pb schrieb:

    Hi!

    Es gibt mehrere Vorgehensweisen. Aber wenn du wissen willst wieviel Zeiger auf einen Speicherbereich zeigen kommst du kaum um einen Refcounter rum.

    Hm, eigentlich interessiert mich das nur sekundär.
    Mein Problem ist, dass ich in einer Methode anonyme Objekte mit new erzeuge und diese in einer anderen Klasse eintrage. Nun dachte ich mir, dass ich im Destruktor dieser anderen Klasse alle diese eingetragenen Objekte mit delete lösche.

    Oder wie ist in C++ das Vorgehen mit anonym mit new erzeugten Objekten?

    Das schöne an Smartpointern ist ja, das der Speicher automatisch freigegeben wird und du dich um nichtsmehr kümmern musst.
    Die Speicherfreigabe geschieht auch im falle von Ausnahmen:

    Heisst das, dass man kein delete mehr braucht?

    Ciao



  • Das delete steht im Dtor der Smartpointerklasse. Objekte von dieser Smartpointerklasse erstellst auf dem Stack, nicht auf dem Heap(new/delete). Sobald dann dieses Objekt den Gültigkeitsbereich verlässt wird der Dtor aufgerufen und automatisch deleted.

    Du brauchst es also noch in der Smartpointerklasse, aber sonst nicht mehr. Die Gefahr, ein delete mal zu vergessen, ist somit eigentlich nicht mehr gegeben.



  • mantiz schrieb:

    Das delete steht im Dtor der Smartpointerklasse. Objekte von dieser Smartpointerklasse erstellst auf dem Stack, nicht auf dem Heap(new/delete). Sobald dann dieses Objekt den Gültigkeitsbereich verlässt wird der Dtor aufgerufen und automatisch deleted.

    Vielen Dank für die Erklärung!
    Das ist aber genau das, was ich eigentlich nicht brauche - Objekte/Zeiger auf dem Stack. Die Objekte, die ich mit new anlege, werden während des ganzen Programmablaufs benötigt und das an verschiedenen Stellen.
    Werde dann wohl am besten auf eine Art Factory-Modell umsteigen, und die Objekte über create-Methoden in ihren Verwaltungsklassen erstellen lassen. In den Destruktoren der Verwalterklassen werden diese Objekte dann wieder deleted.
    Oder gibt es auch ne Art SmartPointer für den Heap?

    Ciao



  • Versteh' ich jetzt nicht so ganz. Die Objekte, auf die der Smartpointer zeigt, die werden weiterhin auf dem Heap angelegt. Lediglich die Objekte der Smartpointer werden auf dem Stack angelegt und diese sind wenn überhaupt nur minimal größer, als die Variable, die den per new erzeugten Zeiger enthält.
    Also, ob nun die Variable, die sowieso auf dem Stack landet, oder das Objekt einer Smartpointerklasse, dürfte eigentlich egal sein.



  • Hm, dann hab ich Deine Erklärung wohl missverstanden, weil da stand, dass Objekte, auf welche die Smartpointerklasse zeigt auf dem Stack erstellt werden.

    Kenne mich wie gesagt mit Smartpointern nicht aus.
    Was passiert denn, wenn ich in einer Methode ein Objekt mittels Smartpointer erstelle und diesen dann einer anderen Klasse übergebe und die Methode, in welcher der Smartpointer erstellt wurde beendet wird?

    Ciao



  • Hi!

    Kommt auf die Art des SmartPtr an. Wenn du Referenzenzählung machst passiert garnichts. Dann wird der Speicher erst freigegeben sobald keine Instanz mehr den Speicher verwendet.

    grüße



  • Jop, in solch' einem Fall sollte man wohl Referenzzählung verwenden.

    Die Klasse kapselt nur die new/delete-Aufrufe, sehr elementar sieht das ganze so aus:

    template<class C>
    class SmartPtr {
        public:
            SmartPtr(C* ob) : m_Object(ob) {
            }
            ~SmartPtr() {
                delete m_Object();
            }
        private:
            C* m_Object;
    };
    

    verwenden kannst Du das dann so:

    SmartPtr<Klasse1> ptr( new Klasse1() );
    

    Das Objekt von Klasse1 wird ganz normal auf dem Heap platziert, aber das Objekt der Klasse SmartPtr<Klasse1> landet auf dem Stack, also wird der Dtor aufgerufen, sobald das Objekt vom SmartPtr<Klasse1> den Gültigkeitsbereich verlässt, dort wird dann delete aufgerufen.
    Jetzt kann man in der Klasse noch nen Member einfügen, der bei jedem neuen Zeiger erhöht wird und im Dtor runterzählt und erst, wenn der Zähler auf 0 steht, dann wird delete aufgerufen.
    Dann kann man noch Operatoren überladen, irgendwie muss man ja auch auf das Objekt zugreifen, welches im SmartPtr gehalten wird. 🙂



  • Danke für die Tips!

    mantiz schrieb:

    Jop, in solch' einem Fall sollte man wohl Referenzzählung verwenden.

    Das Objekt von Klasse1 wird ganz normal auf dem Heap platziert, aber das Objekt der Klasse SmartPtr<Klasse1> landet auf dem Stack, also wird der Dtor aufgerufen, sobald das Objekt vom SmartPtr<Klasse1> den Gültigkeitsbereich verlässt, dort wird dann delete aufgerufen.
    Jetzt kann man in der Klasse noch nen Member einfügen, der bei jedem neuen Zeiger erhöht wird und im Dtor runterzählt und erst, wenn der Zähler auf 0 steht, dann wird delete aufgerufen.

    Ohne den würde ja das Objekt entfernt, wenn ich den SmartPointer aus der Methode, in der er erzeugt wurde einer anderen Klasse übergebe und die Methode dann verlasse, oder?

    Wie sieht denn so ein Zähler codemäßig aus, d.h. wo ist er zu platzieren?

    [/quote]
    Dann kann man noch Operatoren überladen, irgendwie muss man ja auch auf das Objekt zugreifen, welches im SmartPtr gehalten wird. :)[/quote]

    Liefert der Standard autopointer schon so eine Funktionalität mit Referenzzählung? Muss ich doch noch mal wühlen!


Anmelden zum Antworten