Menu
Coddy logo textTech

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 zwracanego

Przeciąż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.

challenge icon

Wyzwanie

Łatwy

Zbudujmy 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ę Formatter z przeciążonymi metodami format(), które obsługują różne scenariusze:
    • Metoda, która przyjmuje pojedynczy argument typu std::string i wypisuje: Message: <text>
    • Metoda, która przyjmuje argument typu std::string oraz poziom priorytetu typu int i wypisuje: [Priority <priority>] <text>
    • Metoda, która przyjmuje argument typu std::string oraz znacznik czasu typu double i wypisuje: [<timestamp>s] <text>
    • Metoda, która przyjmuje trzy parametry typu std::string (nadawcę, odbiorcę i wiadomość) i wypisuje: From <sender> to <receiver>: <message>
    Wszystkie metody powinny mieć nazwę format(): kompilator wybierze właściwą na podstawie argumentów.
  • main.cpp: Odczytaj cztery dane wejściowe (każdą w osobnym wierszu):
    1. Prosty tekst wiadomości
    2. Poziom priorytetu (liczba całkowita)
    3. Znacznik czasu (liczba typu double)
    4. Nazwa nadawcy

    Utwórz obiekt Formatter i 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 ready

Zwróć 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;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C++ online