Pointer - Unterschied zwischen Pointer auf Klasse und Klassen-variable?
-
Jetzt hat mein Programm inzwischen 3500 Zeilen, viele pointer und einige klassen, aber Pointer auf Klassen versteh ich immer noch nicht.
angenommen ich hab folgende Klasse:
class MyClass { MyClass(void); void methodA(); void methodB(); };
den Aufruf hab ich bisher meist so gemacht:
MyClass* classVar1; classVar1 = new MyClass; cout << classVar1->methodA(); cout << classVar1->methodB(); // und irgendwo muss sie wohl wieder freigegeben werden: delete classVar1;
folgendes funktioniert aber ja auch:
MyClass classVar2; cout << classVar2.methodA(); cout << classVar2.methodA();
was ist der Unterschied?
Das eine muss ich freigeben und das ander nicht. ist das alles?Gruß,
Stefan
-
oh Shit!!!
das cout geht natürlich nicht, da ich void geschrieben hab!Also denkt euch das "cout" oben bitte weg!
-
Informier dich über Stack und Heap. Steht in jeden Tutorial/Buch.
-
ok, danke für den tipp!
hat mir weitergeholfen.Stack
int a; //or MyClass classVar2;
Der Speicher wird auf dem Stack angelegt, und wird vom Compiler automatisch wieder freigegeben, wenn der Bereich in dem die Variable definiert wurde verlassen wird. (zum Beispiel beim verlassen der Methode)
Der Stack ist schneller als der Heap, allerdings ist seine Größe beschränkt.Heap
MyClass* classVar1 = new MyClass;
Hier wird speicher im Heap belegt. Der Heap ist der gesammte Arbeitsspeicher+Auslagerungsdatei (Virtueller Speicher). Objekte, die auf dem Heap liegen werden nicht gelöscht (achtung MEMORY LEAK!), bis man
delete classVar1;
aufruft.Im Allgemeinen sollten größere Datenstrukturen auf dem Heap abgelegt werden. (Klassen und structs)
mfg, Stefan
Ps:
Steht in jeden Tutorial/Buch.
Bücher: zu Teuer, zu schlecht zu durchsuchen, und nehmen zuviel Platz im Regal weg. Hab noch eine Reihe 10 Jahre alter Pascal Bücher, in die ich eigentlich fast nie reingeschaut hab
-
StefanXP schrieb:
Im Allgemeinen sollten größere Datenstrukturen auf dem Heap abgelegt werden. (Klassen und structs)
Nein, im Allgemeinen sollte sie auf dem Stack angelegt werden., ausser wenn konkrete Gründe dagegensprechen.
-
hum?
hab die info von
http://c.ittoolbox.com/documents/document.asp?i=2112
http://www.tutorials.de/tutorials136673.html (2. & 4. Eintrag)Meintest du dass normale Klassen und Structs auf den Stack sollten, oder auch große Klassen????
Wenn ich einen Graphen mit 10000 Knoten aufbaue, dann sollte der aber schon aufm heap, oder??
...a little confused...
-
StefanXP schrieb:
Wenn ich einen Graphen mit 10000 Knoten aufbaue, dann sollte der aber schon aufm heap, oder??
Der Graph bleibt am Stack - die Konten allerdings sind dynamisch, deshalb sollten sie auf dem Heap liegen.
-
Die Argumentation ist lächerlich: Erstens bringt er Call-by-Value und den Stack durcheinander. Er sagt sinngemäß, dass Call-by-Value für große Objekte schlecht ist, deshalb soll man den Stack nicht benutzen. Unlogisch. Zweitens: «Also, there is no save way to protect the stack space from being overwritten (other than adjusting the ESP register yourself).» Dazu fehlen mir glatt die Worte, das muss man sich einfach mal selbst auf der Zunge zergehen lassen.
Enthält ebenfalls logisch falsche Argumentation. Klar, wenn der Stack begrenzt ist, dann gehören sehr große Objekte nicht auf den Stack. Aber erstens ist nicht klar, ab wann etwas «groß» ist. Der Stack ist unter Linux normalerweise unbegrenzt, MSVC räumt ihm AFAIk einige MB ein ... dh «große» Objekte sind fast ausschließlich große Arrays ab vielleicht 100000 Elementen. «Außerdem gehöhren instanzen also objekte die aus klassen gebildet wurden, prinziell auf den Heap.» Dafür wird keine Begründung angegeben. Ist ja auch Nonsens.
Ich hoffe du informierst dich nicht nur aus solchen dubiosen Quellen.
Ohne mich jetzt als definitive Quelle aller Weisheit darzustellen (dazu lese man Stroustrup und andere Bibeln): Objekte dann auf den Stack, wenn das automatische Zerstören am Blockende gewünscht wird. Dann auf den Heap, wenn man die Lebensdauer selbst kontrollieren muss. Bei sehr großen Objekten, bei denen die Gefahr eines Stacküberlaufs besteht, sollte man eine Ausnahme machen.
das Beispiel vom ersten Link hätt ich btw so formuliert:
class MyClass { // int32 pi32Array[100000]; gutes Beispiel gegen Ungarische Notation ;) int32 *array; public: MyClass() : array(new int32[100000]) {} ~MyClass() { delete[] array; } ... };
Dann kann die Klasse auf den Stack gelegt werden, so dass die Gefahr von Memoryleaks gebannt ist. Andererseits wird der Stack nicht mit diesem riesigen Array belastet. Ausserdem kann man so einen besseren Zuweisungsoperator schreiben, indem man die Pointer vertauscht ...
Zum Graph-Beispiel: Da die Zahl der Knoten nicht fest ist, liegen die wahrscheinlich sowieso auf dem Heap. Die eigentliche Klasse ist gar nicht so groß ...
-
super, danke!
das schafft klarheit!Dann werd ich jetzt mal die Speicherverwaltung in meinem Programm neu gestalten
Hatte bisher alles auf heap, und hab mein Memoryleak nicht in den griffbekommen.Über dein Beispiel mit dem >: array(new int32[100000])< muss ich wohl noch einwenig nachdenken.
-
Über dein Beispiel mit dem >: array(new int32[100000])< muss ich wohl noch einwenig nachdenken.
Das ist eine Initialisiererliste (die hier nur aus einem Element besteht). array wird mit new int32[100000] initialisiert. Das ist in diesem Fall (weil int32* ein primitiver Typ ist) gleichbedeutend mit einer Zuweisung im Konstruktor:
MyClass() { array = new int32[100000]; }