Forum: PC-Programmierung C++ Instanz bilden


von Bjarne (Gast)


Lesenswert?

Hallo

ich bin interessiert an C++ und habe da als quasi Anfänger eine Frage.

Was ist der Unterschied zwischen den beiden Wegen ein Objekt zu 
erzeugen?

1)
CKlasse iklasse1;
int ret = iklasse1.getIrgendwas();

und

2)
CKlasse *iklasse2 = new CKlasse();
int ret = iklasse2.getIrgendwas();


Ich habe die Instanzen in einer Funktion xyz erstellt und wie es 
aussieht,
wird bei 1) der Destruktor aufgerufen und in 2) nicht, wenn die Funktion 
xyz verlassen wird.

Bei 2) musste ich delete(iklasse2) am Ende der Funktion xyz aufrufen 
damit der Destruktor von iklasse2 in 2) aufgerufen wird.

Des Weiteren "vermute" ich dass Objekt iklasse1 in 1) auf dem Stack 
angelegt wurde und iklasse2 in 2) zur Laufzeit auf dem Heap.

In einer Endlosschleife würde ich das Objekt iklasse1 immer erstellen 
und zerstören. Bei iklasse2 würde ich ohne das delete(iklasse2) 
permanent neue Objekte erstellen (Speicherleck).

Ist das soweit richtig?
Wann macht die "statische" Erzeugung des Objektes zur Kompilerzeit Sinn
und wann die "dynamische" zur Laufzeit?



Danke und Gruß

von g457 (Gast)


Lesenswert?

> Wann macht die "statische" Erzeugung des Objektes zur Kompilerzeit Sinn
> und wann die "dynamische" zur Laufzeit?

Statisch:
- wenn das Objekt am Ende des Scopes zerstört werden soll oder muss
- wenn man keinen Heap hat
- wenn man auf Performance Wert legt

Dynamisch:
- wenn man voher nicht weiß, wieviele Objekte man braucht
- wenn die Objektlebenszeit größer sein soll als der aktuelle Scope

von Christopher C. (trihexagon)


Lesenswert?

new und delete sollte man eigentlich nur noch in legacy Code verwenden 
(Außnahme Qt GUI), stattdessen benutzt man Smartpointer, d.h. unique_ptr 
und shared_ptr.
1
#include <memory>
2
//...
3
4
std::unique_ptr<CKlasse> iklasse = std::make_unique<CKlasse>();
5
6
//oder halt kürzer
7
auto iklasse = std::make_unique<CKlasse>();

von Peter II (Gast)


Lesenswert?

Christopher C. schrieb:
> new und delete sollte man eigentlich nur noch in legacy Code verwenden
> (Außnahme Qt GUI), stattdessen benutzt man Smartpointer, d.h. unique_ptr
> und shared_ptr.

wo soll da der Vorteil sein?

von Dumdi D. (dumdidum)


Lesenswert?

Wie ist der Stack speichermäßig  eigentlich begrenzt? D.h. was ist bei 
sehr sehr großen Objekten?

von Thorsten (Gast)


Lesenswert?

Peter II schrieb:
> wo soll da der Vorteil sein?

Automatische Freigabe des allokierten Objektes, sobald es keinen Zeiger 
mehr darauf gibt.

von Christopher C. (trihexagon)


Lesenswert?

Echt nervig, diese Editierfunktion. Wenn einem noch was eingefallen ist, 
das schnell hinzufügen möchte und ein Anderer vor dem Absenden 
antwortet, ist der geschriebene Texte einfach weg.

Warum man das macht, wollte ich noch dazu schreiben...

Peter II schrieb:
> Christopher C. schrieb:
>> new und delete sollte man eigentlich nur noch in legacy Code verwenden
>> (Außnahme Qt GUI), stattdessen benutzt man Smartpointer, d.h. unique_ptr
>> und shared_ptr.
>
> wo soll da der Vorteil sein?

Dass der Speicher bzw. das Objekt automatisch am Ende des Scopes 
freigegeben wird. Also kein explizites delete, das man vergessen könnte. 
shared_ptr betreibt auch noch Referenzzählung.

von Peter II (Gast)


Lesenswert?

Christopher C. schrieb:
> Dass der Speicher bzw. das Objekt automatisch am Ende des Scopes
> freigegeben wird. Also kein explizites delete, das man vergessen könnte.
> shared_ptr betreibt auch noch Referenzzählung.

Wenn ich will das das object am eine vom Scopes freigegeben wird, nehme 
ich auch kein New dann lege ich es einfach auf den Stack.

von Christopher C. (trihexagon)


Lesenswert?

Peter II schrieb:
> Christopher C. schrieb:
>> Dass der Speicher bzw. das Objekt automatisch am Ende des Scopes
>> freigegeben wird. Also kein explizites delete, das man vergessen könnte.
>> shared_ptr betreibt auch noch Referenzzählung.
>
> Wenn ich will das das object am eine vom Scopes freigegeben wird, nehme
> ich auch kein New dann lege ich es einfach auf den Stack.

Wenn du ein Objekt dynamisch anlegen musst, geht das schlecht. Z.B. 
Puffer mit erst zur Laufzeit bekannter Länge.

Scope kann auch Objekterzeugung->Objektzerstörung bedeuten, also im 
Kontext einer Klasse.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Bjarne schrieb:
> Des Weiteren "vermute" ich dass Objekt iklasse1 in 1) auf dem Stack
> angelegt wurde und iklasse2 in 2) zur Laufzeit auf dem Heap.

In C++ gibt's drei Arten von Speicher bzw. Lebensdauer der Objekte:

statisch: Das Objekt lebt bis zum Ende des Programms
automatisch: Das Objekt lebt bis zum Verlassen des Blocks, in dem es 
definiert ist
dynamisch: Das Objekt lebt, bis es explizit wieder freigegeben wird

> In einer Endlosschleife würde ich das Objekt iklasse1 immer erstellen
> und zerstören. Bei iklasse2 würde ich ohne das delete(iklasse2)
> permanent neue Objekte erstellen (Speicherleck).

Ja, richtig. Wenn du new benutzt (dynamisches Objekt), dann bist du 
dafür verantwortlich, das Objekt wieder zu zerstören, wenn du es nicht 
mehr brauchst. Die angesprochenen Smartpointer dienen dazu, dir diese 
Verantwortung weitestgehend abzunehmen.

> Wann macht die "statische" Erzeugung des Objektes zur Kompilerzeit Sinn
> und wann die "dynamische" zur Laufzeit?

Eigentlich ganz einfach: Wenn es nicht möglich ist, es zur Compilezeit 
anzulegen, muss man es zur Laufzeit anlegen. Es kann z.B. sein, dass man 
viele Objekte anlegen muss abhängig von Daten, die erst zur Laufzeit 
bekannt sind, beispielsweise, weil man sie aus einer Datei lädt. Dann 
hat man zur Compilezeit keine Info darüber, wieviele Objekte man braucht 
und von welchem Typ sie sind (Stichwort Polymorphie).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.