Menu
Coddy logo textTech

Destruktor im Detail

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 24 von 104.

Ein Destruktor ist eine spezielle Memberfunktion, die automatisch ausgeführt wird, wenn ein Objekt zerstört wird. Seine Hauptaufgabe besteht darin, Ressourcen freizugeben, die das Objekt während seiner Lebensdauer erworben hat, etwa dynamisch zugewiesenen Speicher, Dateihandles oder Netzwerkverbindungen.

Der Destruktor hat denselben Namen wie die Klasse, dem eine Tilde vorangestellt ist: ~. Er nimmt keine Parameter entgegen und hat keinen Rückgabetyp:

class FileHandler {
    std::string filename;
    int* buffer;
public:
    FileHandler(std::string name, size_t size) 
        : filename(name), buffer(new int[size]) {
        std::cout << "Opening " << filename << "\n";
    }
    
    ~FileHandler() {
        delete[] buffer;
        std::cout << "Closing " << filename << "\n";
    }
};

Destruktoren werden in diesen Situationen automatisch aufgerufen:

  • Stack-Objekte verlassen den Gültigkeitsbereich
  • delete wird für ein heap-allokiertes Objekt aufgerufen
  • Die Lebensdauer eines temporären Objekts endet
void example() {
    FileHandler f1("data.txt", 100);    // Konstruktor aufgerufen
    
    FileHandler* f2 = new FileHandler("log.txt", 50);
    delete f2;                           // Destruktor für f2 aufgerufen
    
}   // Destruktor für f1 aufgerufen (verlässt den Gültigkeitsbereich)

Im Gegensatz zu Konstruktoren kann eine Klasse nur einen Destruktor haben. Du kannst ihn nicht überladen.

Wenn du keinen definierst, erzeugt der Compiler einen Standarddestruktor, der nichts Besonderes tut – er zerstört einfach jedes Mitglied. Bei Klassen, die Ressourcen verwalten, musst du deinen eigenen schreiben, um Speicherlecks zu verhindern.

challenge icon

Aufgabe

Einfach

Erstelle einen Sitzungsmanager, der aktive Benutzersitzungen verfolgt und zeigt, wie Destruktoren Ressourcen automatisch bereinigen, wenn Objekte zerstört werden – unabhängig davon, ob sie den Gültigkeitsbereich verlassen oder explizit gelöscht werden.

Du erstellst zwei Dateien, um deinen Code zu organisieren:

  • Session.h: Definiere eine Session-Klasse, die eine aktive Benutzersitzung mit dynamisch zugewiesenen Daten darstellt. Deine Klasse sollte Folgendes enthalten:
    • Private Member: einen username (String), eine sessionId (Ganzzahl) und einen Zeiger auf ein Ganzzahl-Array namens activityLog, das Benutzeraktionen verfolgt, sowie ein logSize für die Arraygröße
    • Einen Konstruktor, der einen Benutzernamen, eine Sitzungs-ID und eine Protokollgröße entgegennimmt. Er sollte das Aktivitätsprotokoll-Array auf dem Heap zuweisen, alle Elemente mit 0 initialisieren und "Session <sessionId> started for <username>" ausgeben
    • Einen Destruktor, der den zugewiesenen Speicher freigibt und "Session <sessionId> ended for <username>" ausgibt
    • Eine logActivity(int activityCode)-Methode, die den Aktivitätscode im nächsten verfügbaren Eintrag speichert (die aktuelle Position soll intern verfolgt werden)
    • Eine getActivityCount()-Methode, die zurückgibt, wie viele Aktivitäten protokolliert wurden
    • Eine getUsername()-Methode, die den Benutzernamen zurückgibt
  • main.cpp: Veranschauliche das Verhalten von Destruktoren in verschiedenen Szenarien. Lies einen Benutzernamen und eine Protokollgröße aus der Eingabe ein (jeweils in einer eigenen Zeile), und führe anschließend Folgendes aus:
    • Erstelle mit geschweiften Klammern { } einen Gültigkeitsbereich und erstelle darin eine auf dem Stack zugewiesene Session mit dem eingegebenen Benutzernamen, der Sitzungs-ID 101 und der eingegebenen Protokollgröße. Protokolliere zwei Aktivitäten mit den Codes 1 und 2 und gib anschließend "Stack session activities: <count>" aus. Wenn der Block endet, sollte der Destruktor automatisch ausgeführt werden.
    • Gib nach dem Block "Stack session destroyed" aus
    • Erstelle mithilfe von Session eine auf dem Heap zugewiesene new mit dem Benutzernamen "Guest", der Sitzungs-ID 202 und der Protokollgröße 3. Protokolliere eine Aktivität mit dem Code 5, gib "Heap session activities: <count>" aus und lösche sie anschließend explizit mit delete.
    • Gib nach dem Löschen "Heap session destroyed" aus

Diese Aufgabe zeigt die beiden wichtigsten Arten, wie Destruktoren aufgerufen werden: automatisch, wenn Objekte auf dem Stack ihren Gültigkeitsbereich verlassen, und manuell, wenn du Objekte auf dem Heap löschst. Beide Wege sollten das dynamisch zugewiesene Aktivitätsprotokoll ordnungsgemäß freigeben, um Speicherlecks zu verhindern.

Binde deine Header-Datei in main.cpp mit #include "Session.h" ein.

Probier es selbst

#include <iostream>
#include <string>
#include "Session.h"

using namespace std;

int main() {
    // Eingabe lesen
    string username;
    int logSize;
    getline(cin, username);
    cin >> logSize;
    
    // TODO: Erstelle einen Scope-Block mit geschweiften Klammern { }
    // Innerhalb des Blocks:
    //   - Erstelle eine stack-allokierte Session mit dem eingegebenen Benutzernamen, der Session-ID 101 und der eingegebenen Log-Größe
    //   - Protokolliere zwei Aktivitäten mit den Codes 1 und 2
    //   - Print "Stack session activities: <count>"
    // Wenn der Block endet, wird der Destruktor automatisch ausgeführt
    
    // TODO: After the block, print "Stack session destroyed"
    
    // TODO: Erstelle eine heap-allokierte Session mit new
    //   - Benutzername: "Guest", Session-ID: 202, Log-Größe: 3
    //   - Protokolliere eine Aktivität mit dem Code 5
    //   - Print "Heap session activities: <count>"
    //   - Lösche die Session
    
    // TODO: After deletion, print "Heap session destroyed"
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C++-Compiler