Eigene Objekte nutzen: Stack vs. Heap



  • Hallo,

    ich habe eine Klasse Interpolation geschrieben, die versch. Arten der Interpolation implementiert (z.B. bilineare). Ich kann diese Klasse nun ja auf zwei Arten nutzen:

    Interpolation* ipol_a = new Interpolation(); // Nutzung 1
    Interpolation ipol_b; // Nutzung 2
    

    Zunächst: Bei welcher Nutzung erstelle ich das Objekt auf dem Stack und bei welchem auf dem sog. Heap? Und was war nochmal genau der Unterschied?

    Wenn ich meine Klasse Interpolation nun in einer anderen Methode einer anderen Klasse einfach als lokales Objekt nutzen will, welche Art der Nutzung sollte ich dann verwenden?

    Wenn das Objekt ein privates Member werden soll, welche Art der Nutzung ist dann zu bevorzugen?

    Viele Grüße, mbu.



  • mbu schrieb:

    Zunächst: Bei welcher Nutzung erstelle ich das Objekt auf dem Stack und bei welchem auf dem sog. Heap? Und was war nochmal genau der Unterschied?

    1 ist auf dem Heap (erkennbar am 'new'), wo 2 landet, hängt davon ab, wo du bist. (lokale Variablen landen auf dem Stack, globale und statische Variablen im Data Segment, Klassenmember dort, wo ihre Mutterklasse angelegt wurde)

    Und wenn du keine deutlichen Gründe dafür hast, den Heap zu verwenden, solltest du darauf verzichten - da mußt du selber daran denken, wann und wo du dein Objekt wieder freigeben willst (C++ hat keinen eingebauten Garbage Collector).

    Wenn ich meine Klasse Interpolation nun in einer anderen Methode einer anderen Klasse einfach als lokales Objekt nutzen will, welche Art der Nutzung sollte ich dann verwenden?

    Variante 2 - die lokale Variable landet auf dem Stack und wird bei Funktionsende automatisch zerstört.

    Wenn das Objekt ein privates Member werden soll, welche Art der Nutzung ist dann zu bevorzugen?

    ebenfalls Variante 2 - die Variable wird im Inneren des anderen Objekts gelagert und im Rahmen des Objekt-Destruktors zerstört.



  • Vielen Dank soweit.

    Was gäbe es denn für Gründe, ein Objekt auf dem Heap zu erstellen? Kannst Du da ein Beispiel geben?

    Wenn ich mir den Code von einigen Leuten anschaue, dann schmeissen die nur um sich mit Variablen, die auf dem Heap erstellt werden.

    Gruß, mbu.



  • Ein Grund für die Verwendung von Heap-Objekten ist das "Überleben" des Objekts - wenn du es aus der Funktion herausgeben willst, mußt du es entweder kopieren (ist manchmal teuer oder unmöglich) oder einen Pointer darauf übergeben (da lokale Objekte am Funktionsende zerstört werden, kannst du dafür kein Stack-Objekt verwenden). Ein anderer Grund sind Daten, deren Größe sich ändern kann (meistens dynamisch angelegte Arrays) - dann aber normalerweise innerhalb einer Klasse gekapselt, die sich um die Speicherverwaltung kümmert (z.B. vector<>).

    PS: Und polymorphe Objekte können auch leichter über den Heap verwaltet werden.



  • mbu schrieb:

    ...Was gäbe es denn für Gründe, ein Objekt auf dem Heap zu erstellen?...

    Klassiker sind:
    - sehr große/viele Objekte
    - "Scope probleme" (Objekt muss über den Scope hinaus gültig bleiben)

    mbu schrieb:

    ...
    Wenn ich mir den Code von einigen Leuten anschaue, dann schmeissen die nur um sich mit Variablen, die auf dem Heap erstellt werden....

    Ist auch vollkommen in Ordnung so.
    Letztlicg geht es auch nicht anders, weil man zumindestens einen Zeiger als Stackobjekt braucht, um auf ein Heap-Objekt zuzugreifen.
    Stackobjekte haben einfach große Vorteile für viele "Standardaufgaben".

    Gruß,

    Simon2.



  • Simon2 schrieb:

    mbu schrieb:

    ...Was gäbe es denn für Gründe, ein Objekt auf dem Heap zu erstellen?...

    Klassiker sind:
    - Laufzeitpolymirphie ("Basisklassenpointer und Aufruf von virtual functions")

    Das ist kein Grund.



  • Laufzeit-Polymorphie geht auch mit Stackobjekten. Das Gegenteil ist irgendwie ein Mythos...

    Objekte mit new erzeugen, mache ich dann, wenn ich Objekte dynamisch erzeugen muß. Z.B. weil ich zur Compilerzeit noch nicht weiß, ob ich Typ A oder Typ B erzeugen will. Oder ob ich keinen von beiden Typ will?

    A *a = 0;
    B *b = 0;
    if(....)
       a = new A();
    else
       b = new B();
    

    Überall wo ich eine dynamische Entscheidung brauche, komme ich meistens mit Pointern weiter. Aber ich denke immer erstmal an Stackobjekte. Merke ich, das ich damit meine Aufgabe nicht oder umständlich lösen kann, greife ich zu Heapobjekten.



  • Bashar schrieb:

    Simon2 schrieb:

    mbu schrieb:

    ...Was gäbe es denn für Gründe, ein Objekt auf dem Heap zu erstellen?...

    Klassiker sind:
    - Laufzeitpolymirphie ("Basisklassenpointer und Aufruf von virtual functions")

    Das ist kein Grund.

    Artchi schrieb:

    Laufzeit-Polymorphie geht auch mit Stackobjekten. ...

    OK, habe wohl etwas zu stark verkürzt:

    neue Formulierung schrieb:

    - Laufzeitpolymorphie ("Basisklassenpointer und Aufruf von virtual functions") in den meistverwendeten StdLib-Containern

    Gruß,

    Simon2.



  • Du kannst auch Pointer auf Stackobjekte in Container packen.



  • Bashar schrieb:

    Du kannst auch Pointer auf Stackobjekte in Container packen.

    Japp - habe das Argument "Wann Pointer ?" falsch auf "Wann Heapobjekte ?" übertragen. Mein Fehler...

    Gruß,

    Simon2.



  • Bashar schrieb:

    Du kannst auch Pointer auf Stackobjekte in Container packen.

    Vorausgesetzt, der Container wird wieder freigegeben/bereinigt, bevor die aktuelle Funktion verlassen wird (OK, das hat weniger mit Polymorphie als mit Scoping zu tun, aber dabei spielt doch beides rein).


Anmelden zum Antworten