Menu
Coddy logo textTech

Verschachtelte & innere Klassen

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

Eine geschachtelte Klasse ist eine Klasse, die innerhalb einer anderen Klasse definiert ist. Diese Technik hilft dabei, Code zu organisieren, indem verwandte Typen gruppiert werden, und kann die Kapselung verbessern, indem Implementierungsdetails verborgen werden.

class LinkedList {
public:
    class Node {    // Verschachtelte Klasse
        int data;
        Node* next;
    public:
        Node(int d) : data(d), next(nullptr) {}
        friend class LinkedList;
    };
    
private:
    Node* head;
    
public:
    LinkedList() : head(nullptr) {}
};

Die verschachtelte Klasse Node ist eng an LinkedList gekoppelt – sie ergibt nur in diesem Kontext Sinn. Durch das Verschachteln signalisieren wir diese Beziehung und vermeiden es, den globalen Namensraum mit einem generischen Namen wie „Node“ zu verunreinigen.

Verschachtelte Klassen folgen denselben Zugriffsregeln, die Sie gelernt haben. Eine im private-Bereich deklarierte verschachtelte Klasse ist nur innerhalb der äußeren Klasse zugänglich.

Wenn als public deklariert, kann externer Code es mit dem Scope-Operator verwenden:

LinkedList::Node node(42);    // Nur wenn Node öffentlich ist

Ein wichtiges Detail zur Richtung: Eine verschachtelte Klasse ist ein Element der umschließenden Klasse und hat dieselben Zugriffsrechte wie jedes andere Element, daher kann sie auf die privaten Elemente der umschließenden Klasse ohne friend-Deklaration zugreifen. Umgekehrt gilt dies jedoch nicht automatisch — die umschließende Klasse hat keinen Zugriff auf die privaten Elemente der verschachtelten Klasse.

Deshalb deklariert Node im obigen Beispiel friend class LinkedList;: Die friend-Deklaration gewährt der umschließenden Klasse LinkedList Zugriff auf die privaten Member von Node – die eine Richtung, die nicht automatisch erfolgt.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein einfaches Aufgabenverwaltungssystem erstellen, bei dem Aufgaben innerhalb eines Projekts organisiert sind. Dies ist ein perfektes Szenario für verschachtelte Klassen — eine Task ergibt nur im Kontext eines Project Sinn, daher werden wir sie darin verschachteln, um unseren Code organisiert zu halten und eine Verunreinigung des globalen Namensraums zu vermeiden.

Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:

  • Project.h: Definieren Sie eine Project-Klasse, die eine verschachtelte Task-Klasse enthält.

    Ihre verschachtelte Task-Klasse sollte im public-Bereich von Project deklariert werden, damit von außen darauf zugegriffen werden kann. Sie sollte einen Aufgabennamen (string) und einen Abschlussstatus (bool) speichern. Geben Sie ihr einen Konstruktor, der den Namen entgegennimmt und die Aufgabe standardmäßig als unvollständig markiert. Fügen Sie die Methoden complete() zum Markieren als erledigt, isComplete() zum Überprüfen des Status und getName() zum Abrufen des Namens hinzu.

    Die Project-Klasse selbst sollte einen Projektnamen (string) und eine Sammlung von Task-Pointern speichern. Stellen Sie einen Konstruktor bereit, der den Projektnamen entgegennimmt, eine Methode addTask(const std::string& taskName), die eine neue Aufgabe erstellt und zum Projekt hinzufügt, eine Methode completeTask(const std::string& taskName), die eine Aufgabe anhand des Namens findet und abschließt, und eine Methode displayStatus(), die den Projektnamen gefolgt vom Status jeder Aufgabe anzeigt.

    Da Task innerhalb von Project verschachtelt ist, kann die Project-Klasse direkt mit Aufgaben arbeiten. Vergessen Sie nicht, dynamisch zugewiesene Aufgaben im Destruktor zu bereinigen.

  • main.cpp: Führen Sie alles zusammen, indem Sie einen Projektnamen und zwei Aufgabennamen von der Eingabe lesen (insgesamt drei Zeilen). Erstellen Sie ein Project mit dem angegebenen Namen, fügen Sie beide Aufgaben hinzu und zeigen Sie dann den ursprünglichen Status an. Schließen Sie die erste Aufgabe ab und zeigen Sie den Status erneut an, um die Änderung zu verdeutlichen.

    Das Ausgabeformat für displayStatus() sollte wie folgt aussehen:

    Project: <project_name>
      - <task_name>: [incomplete]
      - <task_name>: [complete]

    Verwenden Sie [complete] oder [incomplete] basierend auf dem Status jeder Aufgabe.

Diese Herausforderung zeigt, wie verschachtelte Klassen helfen, verwandte Typen zu organisieren — die Task-Klasse ist eng mit Project gekoppelt und würde für sich allein keinen Sinn ergeben. Durch das Verschachteln signalisieren wir diese Beziehung klar in unserer Codestruktur.

Probier es selbst

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

using namespace std;

int main() {
    // Eingabe lesen
    string projectName;
    string task1Name;
    string task2Name;
    
    getline(cin, projectName);
    getline(cin, task1Name);
    getline(cin, task2Name);
    
    // TODO: Erstellen Sie ein Projekt mit dem angegebenen Namen
    
    // TODO: Fügen Sie beide Aufgaben zum Projekt hinzu
    
    // TODO: Den Anfangsstatus anzeigen
    
    // TODO: Die erste Aufgabe abschließen
    
    // TODO: Den Status erneut anzeigen, um die Änderung zu sehen
    
    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