Warum Objekte auf dem Heap erzeugen?

bigfella

Erfahrenes Mitglied
Hi..
Könnte mir bitte jemand erklären warum man eigentlich Variablen und Objekte auf dem Heap erzeugen sollte? Und warum man diese auch per "delete" wieder löschen sollte?

Was bringt das für einen Vorteil?
Noch was: das ich über den Konstruktor meine Objekte initialisieren kann ist verständlich.
Aber warum braucht man den Destruktor?

Vielen Dank für Eure Hilfe
 
Jedes erzeugte Objekt benötigt Speicherplatz auf dem Arbeitsspeicher. Wenn du immer wieder neue Objekte erzeugst, diese aber nicht wieder per delete löscht, wächst der Speicherbedarf von deinem Programm an. So ähnlich, wie wenn du irgenwelche Dateien erzeugst, diese aber nicht wieder löscht, dann wird deine Festplatte schnell voll.

Und den Destruktor benötigst du um "aufzuräumen", d.h. Speicherplatz von anderen Objekten freizugeben, offene Dateien/Verbindungen/... zu schließen. Natürlich brauchst du nicht in jeder Klasse einen Destruktur.

Die Frage mit dem Heap verstehe ich nicht ganz. Willst du wissen, warum Objekte auf dem Heap und nicht im Stack angelegt werden ?
 
Außerdem ist der Stack meist sehr begrenzt und der Platz reicht dann manchmal einfach nicht aus um die ganzen Objekte anzulegen; das Programm würde dann abgebrochen.

Desweiteren werden automatische Variablen (die auf dem Stack angelegt werden) nach Ende des Blocks in dem sie definiert wurden wieder zerstört - deshalb "automatisch"; es gibt in C++ sogar das (überflüssige) Schlüsselwort "auto" dafür
Code:
auto int x;
 
Code:
#include <iostream.h>
#include <conio.h>

class Cat
{
   public:
      Cat();
      ~Cat();
      int GetAge() const;
      void SetAge(int age);

   private:
      int itsAge;
};
Cat::Cat()
{
   itsAge = 3;
}
Cat::~Cat()
{

}
int Cat::GetAge()const
{
   return itsAge;
}

void Cat::SetAge(int age)
{
  itsAge = age;
}
int main()
{
Cat *Mike= new Cat;
cout<<"\nMike ist "<<Mike->GetAge()<<" Jahre alt.";
delete Mike;
Cat *Mike = new Cat;
Mike->SetAge(9);
cout<<"\nMike ist "<<Mike->GetAge()<<" Jahre alt.";
getch();
return 0;
}

Aber warum kommt dann beim Ausführen "Multiple Declaration for Mike"
Hab es doch per delete wieder gelöscht und dann neu erzeugt?
 
Mit delete gibst du den Speicherbereich frei auf den Mike zeigt.
Mike zeigt jetzt immernoch auf diesen Speicherbereich, nur steht
da nicht mehr viel :-).

Dein Problem:
Du hast dem Compiler doch schon gesagt, dass Mike ein Cat-Pointer ist,
somit ist das beim 2. new Aufruf nicht mehr notwendig.
Schreib einfach
Code:
.
.
.
delete Mike;
Mike = new Cat;
Mike->SetAge(9);
.
.
.
Gruß, Chris
 
Code:
#include <iostream.h>
#include <conio.h>

class Cat
{
   public:
      Cat();
      ~Cat();
      int GetAge() const;
      void SetAge(int age);

   private:
      int itsAge;
};
Cat::Cat()
{
   itsAge = 8;
}
Cat::~Cat()
{

}
int Cat::GetAge()const
{
   return itsAge;
}

void Cat::SetAge(int age)
{
 itsAge = age;
}
int main()
{
Cat *Mike = new Cat;
const Cat *Andi = new Cat;
Cat *const Hans = new Cat;

cout<<"\nMike ist "<<Mike->GetAge()<<" Jahre alt.";
cout<<"\nAndi ist "<<Andi->GetAge()<<" Jahre alt.";
cout<<"\nHans ist "<<Hans->GetAge()<<" Jahre alt."<<endl;

Mike->SetAge(10);
cout<<"\nMike ist "<<Mike->GetAge()<<" Jahre alt.";
Andi->SetAge(10);
cout<<"\nAndi ist "<<Andi->GetAge()<<" Jahre alt.";
Hans->SetAge(10);
cout<<"\nHans ist "<<Hans->GetAge()<<" Jahre alt.";

getch();
return 0;
}

Danke Chris.. hab das mit dem Mikepointer nun auch verstanden.
Hier aber n anderes Problem:
Thema: Konstante Zeiger:
Warum deklarier ich "Mike, Hans, und Andi" unterschiedlich konstant,
bekomme aber dennoch die neu-gesetzten Werte geliefert?
Dachte eigentlich das die Werte doch konstant sind und deshalb bei 8 bleiben?
 
So wie du das machst, bezieht sich const nur auf den Pointer bzw auf das Objekt, nicht auf dessen Speicherinhalt.
Schreibe const int itsAge im private Teil und du kannst das Alter nicht ändern.
(und setAge wird nicht compilieren :-) )!
 
Mike und das Objekt auf das Mike zeigt kannste verändern (ist ja klar, da hier nicht mit const deklariert wurde).

Das Objekt auf das Hans zeigt kannste verändern, da Hans ein konstanter Pointer auf ein veränderbares Objekt ist. (es hilft meistens eine Deklaration von rechts nach links zu lesen: "Cat * const Hans;" => Hans ist ein konstanter Pointer auf ein(e) Cat). Nur, du kannst den Pointer selbst nicht mehr verändern:
Code:
Cat * const Hans = new Cat;
Hans = Mike; /* Fehler ! */

Bei Andi beschwert sich mein Compiler (zu Recht!) das auf das Objekt auf was Andi zeigt die Methode SetAge nicht angewendet werden kann, da die Methode ja nicht als konstant vereinbart wurde und somit (potentiell) den Zustand des Objekts verändert.

Der Vollständigkeit halber die letzte Möglichkeit:
Code:
const Cat * const Tim = new Cat;

/edit: @bigfella hab ich das eigentlich jetzt richtig verstanden das dein Compiler das kompiliert und dir keine Fehlermeldung ausgibt und dir dein C++ Buch um die Ohren schlägt? ;-) (was benutzt du denn für einen Compiler?)
 
Zuletzt bearbeitet:
Zurück