Funkcje przeciążone w C++

1. Pojęcie przeciążania funkcji

Przeciążanie funkcji (ang. function overloading) polega na definiowaniu kilku funkcji o tej samej nazwie, ale różniących się listą parametrów (liczbą, typem lub kolejnością parametrów).

Kompilator C++ potrafi rozróżnić, którą wersję funkcji wywołać, analizując przekazane argumenty.

Przeciążanie funkcji zwiększa:

  • czytelność kodu,
  • spójność nazw,
  • wygodę programowania.

2. Warunki poprawnego przeciążania

Aby funkcje mogły być przeciążone, muszą różnić się sygnaturą, czyli:

2.1 Co może się różnić:

  • liczba parametrów,
  • typy parametrów,
  • kolejność parametrów.

2.2 Co NIE może się różnić:

  • tylko typ zwracany

Przykład błędny:


3. Przykład prostego przeciążania

Wywołania:


4. Jak kompilator wybiera odpowiednią funkcję

Proces ten nazywa się rozstrzyganiem przeciążenia (overload resolution).

Kompilator analizuje:

  1. liczbę argumentów,
  2. ich typy,
  3. możliwość konwersji typów.

Kolejność preferencji:

  1. dokładne dopasowanie,
  2. promocja typów (np. int → double),
  3. konwersja standardowa,
  4. konwersja zdefiniowana przez użytkownika.

5. Przeciążanie z różnymi typami danych


6. Przeciążanie a parametry domyślne

Uwaga: przeciążanie funkcji z parametrami domyślnymi może prowadzić do konfliktów.

Wywołanie:


7. Przeciążanie funkcji a referencje i const

Wywołania:


8. Przeciążanie funkcji z tablicami i wskaźnikami


9. Przeciążanie funkcji a szablony (templates)

Szablony funkcji często zastępują przeciążanie, gdy logika jest taka sama.

Przeciążanie:

Szablon:

Szablony są bardziej uniwersalne, ale przeciążanie bywa czytelniejsze.


10. Przeciążanie funkcji w klasach


11. Najczęstsze błędy

❌ próba przeciążenia tylko typem zwracanym

❌ niejednoznaczne wywołania

❌ konflikt z parametrami domyślnymi

❌ nadmierne przeciążanie jednej funkcji


12. Zalety i wady funkcji przeciążonych

✅ Zalety

  • spójne nazewnictwo,
  • czytelniejszy kod,
  • wygoda użycia.

❌ Wady

  • możliwość niejednoznaczności,
  • trudniejsza analiza kodu,
  • potencjalne błędy kompilacji.

13. Praktyczne zastosowania

  • funkcje matematyczne,
  • obsługa różnych typów danych,
  • biblioteki standardowe (np. cout <<),
  • interfejsy API.