Destruktor in c++

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Destruktor in c++

    Morgen Coding Freunde !

    Heute habe ich mal eine kleine verständniss frage zum Destruktor in c++

    Also wenn ich das richtig verstanden hab läuft das ganze so ab:

    1.Wenn ich ein Objekt erstelle dann befindet sich dieses auf dem Stack.

    2. Wenn der Codeblock abgelaufen ist in dem das Objekt lebt stirbt es da es die Gültigkeit verliert
    beispielsweiße es wird in der Main erstellt stirbt es also nach der Main.. Das passiert immer egal ob es einen Destruktor besitzt oder nicht (bzw gibt es einen Default Destruktor ?)

    3. Allerdings wird dabei nur der Speicher auf dem Stack freigegeben. Falls das Objekt nun aber zusätzlich speicher auf dem Heap reserviert hat entstehen Speicher leks. zum Beispiel ein Array name = new char[4];

    4. Also muss im Destruktor explizit der Speicher auf dem Heap mit delete freigegeben werden

    Ist das so richtig ?
    Wenn ja kann ich mir dann den Destruktor sparen wenn mein Objekt nichts auf dem Heap reserviert oder gehört es einfach zum guten Stil ?

    Wenn das richtig ist was ich oben geschrieben habe dann müsste doch auch folgendes beispiel komplett sinnlos sein oder ?
    cplusplus.com/reference/std/new/operator%20delete%5B%5D/

    Also ich meine abgesehn davon das es die referenz zum delete befehl ist ;)... es müsste doch das Array pt im Konstruktor initailisert werden und delete im Destruktor oder ? Womit dann in diesem Beispiel Konstruktor und Destruktor total sinnlos sind oder ?

    Danke für eure Hilfe
  • 1. Kann man überhaupt ein Objekt auf dem Stack erstellen?
    Ich hab bisher immer new verwendet und somit den Heap genutzt.

    2. Wenn du ein Objekt in der Main erstellst und du bist mit der Main durch, also das Programm wurde erfolgreich abgeschlossen, dann ist es egal weil der reservierte Speicherplatz,
    egal ob Heap oder Stack, wieder freigegeben wird.

    3. Speicherleks können auch auf dem Stack entstehen. Das hat was mit dem Datentyp und deren Größe zutun.

    4. Ja

    Auf einen Destruktor sollte man niemals verzichten, warum auch?
    Solang er nicht ausgeführt wird verbraucht er keine Ressourcen. (Bsp.: siehe 2.)
    Aber er ist zwingend notwendig ihn zu nutzen um reservierten Speicher während der Laufzeit wieder frei zugeben.
    Du musst dir auch Vorstellen das komplexere Programme mehrere Objekte haben. Die brauchen alle Speicher und wenn man diese nicht mehr braucht kann man sie mit delete wieder löschen
    um Speicher zu sparen

    Das Beispiel aus der Referenz ist halt ein einfaches Bespiel zum Verständnis. In diesem Fall ist es sinnlos :)
    Der Befehl new ruft den Konstruktor auf und reserviert Speicherplatz auf dem Heap, während delete den Destruktor aufruft und den Speicherplatz wieder frei gibt.
    Das ist ein wesentlicher Bestandteil der OOP.
    "Irren ist menschlich. Aber wer richtigen Mist bauen will, braucht einen Computer."
  • Hallo nobody!

    Danke für deine Antwort.

    Ja das mit der Main war etwas dumm formuliert;) ... natürlich ist mir klar das es dann egal ist aber wenn du beispielsweiße eine eigene Funtion hättest die in der Main aufgerufen wird und ein Objekt erstellt sobald du wieder von dieser Funktion in die Main spirngst wird das Objekt gelöscht oder ?

    Ja anscheinend kann man Objekte auf dem stack erstellen
    de.wikibooks.org/wiki/C%2B%2B-…erwaltung/_Stack_und_Heap
    wobei ich mich auch frage wie? ich glaube wenn man einfach nur den Konstruktor aufruft wird es auf dem Stack gelegt ?
  • Es werden alle lokalen Variablen auf dem Stack abgelegt!
    Der unterschied ist, durch die benutzung von new wird auf dem Stack ein Verweis auf den Heap abgelegt, sodass der Stack nicht so stark "belastet" wird.

    Beispiel (32Bit System):

    Quellcode

    1. int main()
    2. {
    3. int val = 0; // <- val ist auf Stack (4Bytes)
    4. int *hp = new int; // hp ist aufm Stack (4Bytes), *hp ist aufm Heap reserviert (4Bytes)
    5. delete hp; // Heap *hp wird freigegeben, hp bleibt dennoch auf dem Stack
    6. return 0;
    7. } // val, hp wird vom Stack entfernt, sollte an dieser der Heap von *hp nicht freigeben worden sein entsteht ein Speicherloch (leak), da man auf hp nicht mehr zugreifen kann


    Das obige Beipiel ist für "Builtin-Typen", wie sieht das nun mit Klassen aus, nun Klassen können relativ komplex werden verhalten sich jedoch im Prinzip genaus wie die Standarttypen.
    Jedoch könen Klassen intern dynamisch sein, deswegen gibt es einen Konstruktor und einen Destructor damit man die Möglichkeit hat aufräum und initialisierungs Arbeiten durchzuführen.

    Allgemein kann man sich merken dass bei Standarttypen (auch Strukturen) einfach der Speicher reserviert/freigegeben wird und bei Klassen dannach/davor noch der Konstruktor/Destructor aufgerufen wird.

    Wenn das richtig ist was ich oben geschrieben habe dann müsste doch auch folgendes beispiel komplett sinnlos sein oder ?
    cplusplus.com/reference/std/n…20delete%5B%5D/

    Der new[] bzw delete [] operator Arbeitet mit Arrays, dabei wird auf dem Stack nur ein Verweise abgelegt auf eine Reihe von Objekten im Heap (Speichermässig nacheinander folgend).

    Quellcode

    1. int main () {
    2. myclass * pt; // pt ist auf dem Stack (Pointer auf 32Bit System 4Byte)
    3. pt = new myclass[3]; // 3 Elemente auf dem Heap reservieren (3Byte -> sizeof(myclass)=1)
    4. delete[] pt;
    5. myclass mc; // Klasse auf dem Stack
    6. return 0;
    7. }


    PS: Mit sizeof(obj) kann man die Größe eines Objekts ermitteln.

    Mfg Rushh0ur