Funktionsüberladung
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 57 von 104.
Funktionsüberladung ermöglicht es dir, mehrere Funktionen mit demselben Namen, aber unterschiedlichen Parameterlisten zu definieren. Der Compiler wählt anhand der übergebenen Argumente die richtige Version aus. Dies ist eine wichtige Form des Polymorphismus zur Kompilierzeit.
Damit Überladen funktioniert, müssen sich Funktionen in ihrer Signatur unterscheiden – in der Anzahl der Parameter, ihren Typen oder in 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) aufDer Compiler untersucht jeden Aufruf und ordnet ihn der passenden Überladung zu. Dies geschieht vollständig zur Kompilierzeit, sodass kein Laufzeit-Overhead entsteht.
Wichtig: Der Rückgabetyp allein unterscheidet überladene Funktionen nicht. Folgendes würde einen Compilerfehler verursachen:
int getValue();
double getValue(); // Fehler: kann nicht nur nach Rückgabetyp überladen werdenFunktionsüberladung macht deinen Code intuitiver. Anstatt separate Namen wie addInts, addDoubles und addThreeInts zu erstellen, verwendest du einen einzigen aussagekräftigen Namen und überlässt dem Compiler den Rest.
Aufgabe
EinfachWir erstellen eine Nachrichtenformatierer-Klasse, die die Leistungsfähigkeit von Funktionsüberladung demonstriert. Du erstellst eine Formatter-Klasse mit mehreren format()-Methoden, die verschiedene Eingabetypen verarbeiten. Dadurch kann der Compiler anhand der übergebenen Argumente die passende Version auswählen.
Du organisierst deinen Code auf zwei Dateien:
Formatter.h: Definiere eineFormatter-Klasse mit überladenenformat()-Methoden, die verschiedene Szenarien verarbeiten:- Eine Methode, die einen einzelnen
std::stringentgegennimmt und Folgendes ausgibt:Message: <text> - Eine Methode, die einen
std::stringund eine Prioritätsstufe vom Typintentgegennimmt und Folgendes ausgibt:[Priority <priority>] <text> - Eine Methode, die einen
std::stringund einen Zeitstempel vom Typdoubleentgegennimmt 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>
format()heißen: Der Compiler wählt anhand der Argumente die richtige Methode aus.- Eine Methode, die einen einzelnen
main.cpp: Lies vier Eingaben ein (jeweils in einer eigenen Zeile):- Einen einfachen Nachrichtentext
- Eine Prioritätsstufe (Ganzzahl)
- Einen Zeitstempel (Gleitkommazahl)
- Einen Absendernamen
Erstelle ein
Formatter-Objekt und demonstriere alle vier überladenen Methoden:- Rufe
format()nur mit dem Nachrichtentext auf - Rufe
format()mit dem Nachrichtentext und der Priorität auf - Rufe
format()mit dem Nachrichtentext und dem Zeitstempel auf - Rufe
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 readyBeachte, dass du denselben Methodennamen format() viermal aufrufst, aber jeder Aufruf abhängig von Anzahl und Typen der Argumente eine andere Version ausführt. Das ist Polymorphie zur Compile-Zeit in Aktion: Der Compiler bestimmt, welche Überladung verwendet werden soll, noch bevor das Programm überhaupt ausgeführt wird.
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: Erstelle ein Formatter-Objekt
// TODO: Rufe format() nur mit dem Nachrichtentext auf
// TODO: Rufe format() mit Nachrichtentext und priority auf
// TODO: Rufe format() mit Nachrichtentext und timestamp auf
// TODO: Rufe format() mit sender, "Admin" als Empfänger und Nachrichtentext auf
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamespaces & GültigkeitsbereichEinführung in OOP mit C++Klassen vs. ObjekteDer „this“-ZeigerMethoden (Member-Funktionen)Attribute (Datenmember)Grundlagen zu Ctors & DtorsRückblick – Einfacher Taschenrechner4Klassenattribute
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen und -KlassenZusammenfassung – Bankkontoverwaltung7Vererbung
Grundlagen der VererbungZugriffsebenen bei der VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick – Mitarbeiterhierarchie2Speicherverwaltung
Stack- vs. Heap-SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Intelligente Zeiger in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsbezeichner in C++Zugriffsbezeichner im DetailInformationsverbergungStruct vs. KlasseVerschachtelte und innere KlassenWiederholung – Studierendenverwaltungssystem8Polymorphie
Polymorphie zur Compilezeit vs. LaufzeitFunktionsüberladungVirtuelle Funktionen erneut betrachtetRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIRückblick – Shape-Calculator3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorMove-KonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktor im DetailDrei-/Fünf-/Null-RegelZusammenfassung – String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladung der Operatoren [] und ()TypkonvertierungsoperatorenWiederholung – Matrix-Klasse9Templates
FunktionstemplatesKlassen-TemplatesTemplate-SpezialisierungVariadische TemplatesGrundlagen zu SFINAE und Type TraitsRückblick – Generischer ContainerÜbe selbstständig: Online-C++-Compiler