Przeciążanie funkcji
Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 57 z 104.
Przeciążanie funkcji pozwala definiować wiele funkcji o tej samej nazwie, ale różnych listach parametrów. Kompilator wybiera właściwą wersję na podstawie przekazanych argumentów. Jest to ważna forma polimorfizmu czasu kompilacji.
Aby przeciążanie działało, funkcje muszą różnić się sygnaturą — liczbą parametrów, ich typami lub jednym i drugim:
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); // Wywołuje add(int, int)
calc.add(2.5, 3.7); // Wywołuje add(double, double)
calc.add(1, 2, 3); // Wywołuje add(int, int, int)Kompilator analizuje każde wywołanie i dopasowuje je do odpowiedniego przeciążenia. Dzieje się to w całości podczas kompilacji, więc nie ma narzutu w czasie wykonywania programu.
Ważne: Sam typ zwracany nie odróżnia przeciążonych funkcji. Poniższy kod spowodowałby błąd kompilatora:
int getValue();
double getValue(); // Błąd: nie można przeciążać funkcji wyłącznie na podstawie typu zwracanegoPrzeciążanie funkcji sprawia, że kod jest bardziej intuicyjny. Zamiast tworzyć osobne nazwy, takie jak addInts, addDoubles i addThreeInts, używasz jednej znaczącej nazwy, a resztę pozostawiasz kompilatorowi.
Wyzwanie
ŁatwyZbudujmy klasę formatującą wiadomości, która pokaże możliwości przeciążania funkcji. Utworzysz klasę Formatter z wieloma metodami format(), które obsługują różne rodzaje danych wejściowych, dzięki czemu kompilator wybierze właściwą wersję na podstawie przekazanych argumentów.
Rozmieścisz kod w dwóch plikach:
Formatter.h: Zdefiniuj klasęFormatterz przeciążonymi metodamiformat(), które obsługują różne scenariusze:- Metoda, która przyjmuje pojedynczy argument typu
std::stringi wypisuje:Message: <text> - Metoda, która przyjmuje argument typu
std::stringoraz poziom priorytetu typuinti wypisuje:[Priority <priority>] <text> - Metoda, która przyjmuje argument typu
std::stringoraz znacznik czasu typudoublei wypisuje:[<timestamp>s] <text> - Metoda, która przyjmuje trzy parametry typu
std::string(nadawcę, odbiorcę i wiadomość) i wypisuje:From <sender> to <receiver>: <message>
format(): kompilator wybierze właściwą na podstawie argumentów.- Metoda, która przyjmuje pojedynczy argument typu
main.cpp: Odczytaj cztery dane wejściowe (każdą w osobnym wierszu):- Prosty tekst wiadomości
- Poziom priorytetu (liczba całkowita)
- Znacznik czasu (liczba typu double)
- Nazwa nadawcy
Utwórz obiekt
Formatteri zademonstruj działanie wszystkich czterech przeciążonych metod:- Wywołaj
format(), przekazując tylko tekst wiadomości - Wywołaj
format(), przekazując tekst wiadomości i priorytet - Wywołaj
format(), przekazując tekst wiadomości i znacznik czasu - Wywołaj
format(), przekazując nadawcę, "Admin" jako odbiorcę oraz tekst wiadomości
Na przykład, dla danych wejściowych System ready, 3, 12.5 i Server:
Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System readyZwróć uwagę, że wywołujesz tę samą metodę format() cztery razy, ale każde wywołanie uruchamia inną wersję zależnie od typów i liczby argumentów. To przykład polimorfizmu w czasie kompilacji: kompilator określa, którego przeciążenia użyć, zanim program w ogóle zostanie uruchomiony.
Spróbuj swoich sił
#include <iostream>
#include <string>
#include "Formatter.h"
using namespace std;
int main() {
// Wczytaj dane wejściowe
string message;
getline(cin, message);
int priority;
cin >> priority;
double timestamp;
cin >> timestamp;
cin.ignore();
string sender;
getline(cin, sender);
// TODO: Utwórz obiekt Formatter
// TODO: Wywołaj format() tylko z treścią wiadomości
// TODO: Wywołaj format() z treścią wiadomości i priority
// TODO: Wywołaj format() z treścią wiadomości i timestamp
// TODO: Wywołaj format() z sender, "Admin" jako odbiorcą i treścią wiadomości
return 0;
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneBudowanie i kompilacja C++Pliki nagłówkowe i pliki źródłowePrzestrzenie nazw i zakresWprowadzenie do programowania obiektowego w C++Klasy a obiektyWskaźnik „this”Metody (funkcje składowe)Atrybuty (składowe danych)Podstawy konstruktorów i destruktorówPowtórzenie – prosty kalkulator4Właściwości klas
Elementy instancji a elementy statyczneGettery i setteryStałe funkcje składoweSłowo kluczowe mutableMetody i zmienne statyczneFunkcje i klasy zaprzyjaźnionePodsumowanie – menedżer konta bankowego7Dziedziczenie
Podstawy dziedziczeniaPoziomy dostępu w dziedziczeniuKolejność wywołań konstruktora i destruktoraNadpisywanie metodFunkcje wirtualne i VTableWielokrotne dziedziczenieDziedziczenie wirtualnePowtórzenie — hierarchia pracowników2Zarządzanie pamięcią
Pamięć stosu a stertyWskaźniki i referencjePamięć dynamiczna (new/delete)Inteligentne wskaźniki w C++RAII w C++Podsumowanie — menedżer tablicy dynamicznej5Hermetyzacja
Specyfikatory dostępu w C++Specyfikatory dostępu — szczegółowoUkrywanie informacjiStruktura a klasaKlasy zagnieżdżone i wewnętrznePodsumowanie — system ewidencji studentów8Polimorfizm
Polimorfizm czasu kompilacji i wykonaniaPrzeciążanie funkcjiFunkcje wirtualne — powtórkaCzysto wirtualne funkcjeKlasy abstrakcyjneProjektowanie interfejsów w C++Rzutowanie dynamiczne i RTTIPodsumowanie — kalkulator kształtów3Konstruktory i destruktory
Konstruktor domyślnyKonstruktor z parametramiKonstruktor kopiującyKonstruktor przenoszącyListy inicjalizacyjne konstruktoraKonstruktory delegująceDestruktor — szczegółowe omówienieZasada trzech / pięciu / zeraPodsumowanie — klasa String6Przeciążanie operatorów
Wprowadzenie do przeciążania operatorówPrzeciążanie operatorów arytmetycznychPrzeciążanie operatorów porównaniaOperatory strumieniowePrzeciążanie operatora przypisaniaPrzeciążanie operatorów [] i ()Operatory konwersji typówPodsumowanie — klasa Matrix9Szablony
Szablony funkcjiSzablony klasSpecjalizacja szablonówSzablony wariadycznePodstawy SFINAE i cech typówPodsumowanie — kontener generycznyPoćwicz samodzielnie: Kompilator C++ online