Menu
Coddy logo textTech

Funktionsüberladung

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

Funktionsüberladung ermöglicht es Ihnen, mehrere Funktionen mit demselben Namen, aber unterschiedlichen Parameterlisten zu definieren. Der Compiler wählt die korrekte Version basierend auf den Argumenten aus, die Sie übergeben. Dies ist eine wichtige Form des Polymorphismus zur Kompilierzeit.

Damit Überladung funktioniert, müssen sich Funktionen in ihrer Signatur unterscheiden – der Anzahl der Parameter, ihren Typen oder beidem:

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    int add(int a, int b, int c) {
        return a + b + c;
    }
};

Calculator calc;
calc.add(5, 3);        // Ruft add(int, int) auf
calc.add(2.5, 3.7);    // Ruft add(double, double) auf
calc.add(1, 2, 3);     // Ruft add(int, int, int) auf

Der Compiler prüft jeden Aufruf und ordnet ihn der entsprechenden Überladung zu. Dies geschieht vollständig zur Kompilierzeit, sodass kein Laufzeit-Overhead entsteht.

Wichtig: Der Rückgabetyp allein unterscheidet überladene Funktionen nicht. Das Folgende würde zu einem Compilerfehler führen:

int getValue();
double getValue();  // Fehler: Überladung nur durch den Rückgabetyp ist nicht möglich

Funktionsüberladung macht Ihren Code intuitiver. Anstatt separate Namen wie addInts, addDoubles und addThreeInts zu erstellen, verwenden Sie einen einzigen aussagekräftigen Namen und lassen den Compiler den Rest erledigen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns eine Nachrichtenformatierer-Klasse erstellen, die die Leistungsfähigkeit der Funktionsüberladung demonstriert. Sie werden eine Formatter-Klasse mit mehreren format()-Methoden erstellen, die verschiedene Arten von Eingaben verarbeiten, sodass der Compiler die richtige Version basierend auf den übergebenen Argumenten auswählt.

Sie werden Ihren Code auf zwei Dateien aufteilen:

  • Formatter.h: Definieren Sie eine Formatter-Klasse mit überladenen format()-Methoden, die verschiedene Szenarien abdecken:
    • Eine Methode, die einen einzelnen std::string entgegennimmt und Folgendes ausgibt: Message: <text>
    • Eine Methode, die einen std::string und eine int-Prioritätsstufe entgegennimmt und Folgendes ausgibt: [Priority <priority>] <text>
    • Eine Methode, die einen std::string und einen double-Zeitstempel entgegennimmt und Folgendes ausgibt: [<timestamp>s] <text>
    • Eine Methode, die drei std::string-Parameter (Absender, Empfänger, Nachricht) entgegennimmt und Folgendes ausgibt: From <sender> to <receiver>: <message>
    Alle Methoden sollten format() heißen — der Compiler wird die korrekte Methode basierend auf den Argumenten auswählen.
  • main.cpp: Lesen Sie vier Eingaben ein (jede in einer separaten Zeile):
    1. Einen einfachen Nachrichtentext
    2. Eine Prioritätsstufe (Ganzzahl)
    3. Einen Zeitstempel (Double)
    4. Einen Absendernamen

    Erstellen Sie ein Formatter-Objekt und demonstrieren Sie alle vier überladenen Methoden:

    • Rufen Sie format() nur mit dem Nachrichtentext auf
    • Rufen Sie format() mit dem Nachrichtentext und der Priorität auf
    • Rufen Sie format() mit dem Nachrichtentext und dem Zeitstempel auf
    • Rufen Sie format() mit dem Absender, "Admin" als Empfänger und dem Nachrichtentext auf

Zum Beispiel mit den Eingaben System ready, 3, 12.5 und Server:

Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System ready

Beachten Sie, wie Sie denselben Methodennamen format() viermal aufrufen, aber jeder Aufruf eine andere Version basierend auf den Argumenttypen und der Anzahl aufruft. Dies ist Polymorphie zur Kompilierzeit in Aktion — der Compiler bestimmt, welche Überladung verwendet werden soll, noch bevor das Programm ausgeführt wird.

Spickzettel

Funktionsüberladung ermöglicht es Ihnen, mehrere Funktionen mit demselben Namen, aber unterschiedlichen Parameterlisten zu definieren. Der Compiler wählt basierend auf den beim Kompilieren übergebenen Argumenten die korrekte Version aus.

Funktionen müssen sich in ihrer Signatur unterscheiden – der Anzahl der Parameter, ihren Typen oder beidem:

class Calculator {
public:
    int add(int a, int b) {
        return a + b;
    }
    
    double add(double a, double b) {
        return a + b;
    }
    
    int add(int a, int b, int c) {
        return a + b + c;
    }
};

Calculator calc;
calc.add(5, 3);        // Calls add(int, int)
calc.add(2.5, 3.7);    // Calls add(double, double)
calc.add(1, 2, 3);     // Calls add(int, int, int)

Wichtig: Der Rückgabetyp allein reicht nicht aus, um überladene Funktionen zu unterscheiden:

int getValue();
double getValue();  // Error: cannot overload by return type only

Funktionsüberladung ist eine Form des Polymorphismus zur Kompilierzeit ohne Overhead zur Laufzeit.

Probier es selbst

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

using namespace std;

int main() {
    // Eingaben lesen
    string message;
    getline(cin, message);
    
    int priority;
    cin >> priority;
    
    double timestamp;
    cin >> timestamp;
    cin.ignore();
    
    string sender;
    getline(cin, sender);
    
    // TODO: Ein Formatter-Objekt erstellen
    
    // TODO: format() nur mit dem Nachrichtentext aufrufen
    
    // TODO: format() mit Nachrichtentext und priority aufrufen
    
    // TODO: format() mit Nachrichtentext und timestamp aufrufen
    
    // TODO: format() mit sender, "Admin" als Empfänger und Nachrichtentext aufrufen
    
    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