Menu
Coddy logo textTech

Delegierende Konstruktoren

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

Wenn Sie mehrere Konstruktoren haben, die eine gemeinsame Initialisierungslogik teilen, können Sie delegierende Konstruktoren verwenden, um Code-Duplizierung zu vermeiden. Ein delegierender Konstruktor ruft einen anderen Konstruktor derselben Klasse in seiner Initialisierungsliste auf.

class Player {
    std::string name;
    int health;
    int level;
public:
    // Primärer Konstruktor - erledigt die eigentliche Arbeit
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Delegiert an den primären Konstruktor
    Player(std::string n) : Player(n, 100, 1) {}
    
    // Standardkonstruktor delegiert ebenfalls
    Player() : Player("Unknown") {}
};

Die Delegierung erfolgt in der Initialisierungsliste unter Verwendung des Klassennamens gefolgt von Argumenten. Wenn Player() aufgerufen wird, delegiert er an Player(std::string), welcher dann an den Konstruktor mit drei Parametern delegiert. Die Kette wird vom Zielkonstruktor zurück zum ursprünglichen ausgeführt.

Es gibt eine wichtige Regel: Ein delegierender Konstruktor darf keine weiteren Elemente in seiner Initialisierungsliste haben. Die Delegierung muss das einzige Element sein:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // Fehler! Delegierung kann nicht mit Elementinitialisierung gemischt werden
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Richtig - nur Delegierung
    Item(int i) : Item(i, 0) {}
};

Delegierende Konstruktoren helfen dabei, die Initialisierungslogik an einem Ort zu zentralisieren, wodurch Ihr Code einfacher zu warten ist und weniger anfällig für Fehler durch duplizierten Code wird.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Verbindungseinstellungssystem erstellen, das zeigt, wie delegierende Konstruktoren Code-Duplizierung eliminieren können, indem sie Konstruktoraufrufe miteinander verketten.

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

  • Connection.h: Definieren Sie eine Connection-Klasse, die eine Netzwerkverbindung mit verschiedenen Konfigurationsoptionen darstellt. Ihre Klasse sollte Folgendes enthalten:
    • Private Member: host (string), port (int), timeout (int in Sekunden) und secure (bool)
    • Einen primären Konstruktor, der alle vier Parameter entgegennimmt und alle Member mithilfe einer Initialisierungsliste initialisiert. Dieser Konstruktor sollte "Connection configured: <host>:<port>" ausgeben.
    • Einen Konstruktor, der nur host und port entgegennimmt und an den primären Konstruktor delegiert, wobei timeout standardmäßig auf 30 und secure standardmäßig auf false gesetzt wird.
    • Einen Konstruktor, der nur host entgegennimmt und an den Zwei-Parameter-Konstruktor delegiert, wobei port standardmäßig auf 80 gesetzt wird.
    • Einen Standardkonstruktor, der an den Ein-Parameter-Konstruktor delegiert, wobei host standardmäßig auf "localhost" gesetzt wird.
    • Eine getInfo()-Methode, die einen String im Format "<host>:<port> (timeout: <timeout>s, secure: <yes/no>)" zurückgibt.
  • main.cpp: Demonstrieren Sie die Delegationskette, indem Sie Verbindungen mit verschiedenen Konstruktoren erstellen. Lesen Sie einen Hostnamen und eine Portnummer von der Eingabe ein (jeweils in einer separaten Zeile) und führen Sie dann Folgendes aus:
    • Erstellen Sie eine Connection mit dem Standardkonstruktor.
    • Erstellen Sie eine Connection nur mit dem Host aus der Eingabe.
    • Erstellen Sie eine Connection mit Host und Port aus der Eingabe.
    • Erstellen Sie eine Connection mit dem eingegebenen Host, dem eingegebenen Port, einem Timeout von 60 und secure auf true gesetzt.
    • Geben Sie getInfo() für jede Verbindung aus, eine pro Zeile.

Die Delegationskette fließt wie folgt: Der Standardkonstruktor ruft den Ein-Parameter-Konstruktor auf, welcher den Zwei-Parameter-Konstruktor aufruft, welcher wiederum den primären Vier-Parameter-Konstruktor aufruft. Das bedeutet, dass die Meldung "Connection configured" für jedes erstellte Objekt einmal ausgegeben wird, und zwar immer vom primären Konstruktor.

Geben Sie für den Sicherheitsstatus in getInfo() "yes" aus, wenn secure true ist, andernfalls "no".

Binden Sie Ihre Header-Datei in main.cpp mit #include "Connection.h" ein.

Spickzettel

Ein delegierender Konstruktor ruft einen anderen Konstruktor derselben Klasse in seiner Initialisierungsliste auf, um Code-Duplizierung zu vermeiden:

class Player {
    std::string name;
    int health;
    int level;
public:
    // Primärer Konstruktor
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Delegiert an den primären Konstruktor
    Player(std::string n) : Player(n, 100, 1) {}
    
    // Standardkonstruktor delegiert ebenfalls
    Player() : Player("Unknown") {}
};

Die Delegierung erfolgt in der Initialisierungsliste unter Verwendung des Klassennamens gefolgt von Argumenten. Konstruktoren können eine Delegierungskette bilden, bei der einer an einen anderen delegiert.

Wichtige Regel: Ein delegierender Konstruktor darf keine anderen Member in seiner Initialisierungsliste haben. Die Delegierung muss das einzige Element sein:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // Fehler! Delegierung kann nicht mit Member-Initialisierung gemischt werden
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Korrekt - nur Delegierung
    Item(int i) : Item(i, 0) {}
};

Probier es selbst

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

using namespace std;

int main() {
    // Eingabe lesen
    string host;
    int port;
    cin >> host;
    cin >> port;

    // TODO: Erstelle eine Connection mit dem Standardkonstruktor

    // TODO: Erstelle eine Connection nur mit dem host aus der Eingabe

    // TODO: Erstelle eine Connection mit host und port aus der Eingabe

    // TODO: Erstelle eine Connection mit host aus der Eingabe, port aus der Eingabe, timeout=60, secure=true

    // TODO: Gib getInfo() für jede Verbindung aus, eine pro Zeile

    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