Przeciążanie funkcji
Z Wikipedii
Przeciążanie funkcji (ang. overloading) - skrótowa nazwa na przeciążanie nazwy funkcji; w programowaniu występowanie pod taką samą nazwą wielu funkcji różniących się zestawem argumentów. W trakcie kompilacji bądź parsowania program znajduje właściwą funkcję po liczbie oraz typach argumentów. Możliwe jest więc współistnienie kilku funkcji o tej samej nazwie, lecz różniących się typami argumentów.
Spis treści |
[edytuj] Przykłady
[edytuj] Przykład w języku C++
void funkcja (int); void funkcja (int, char); void funkcja (float, int);
[edytuj] Przykład w języku Object Pascal
procedure Foo(f: integer); overload; procedure Foo(s: string; f: integer); overload; procedure Foo(d: double; f: integer); overload;
Przeciążanie funkcji w języku Object Pascal dostępne jest od środowiska Delphi w wersji 4.
[edytuj] Przykład w języku PL/1
Nieco inaczej przeciążanie nazw realizowano w historycznych już dzisiaj językach. Jako przykład posłużyć może deklaracja rodziny procedur w języku PL/1, w którym definiowano różne procedury, a następnie nazwę nowej procedury i listę procedur wywoływanych przez tą nazwę dla konkretnych przypadków listy argumentów.
Przykład w PL/1:
DCL A GENERIC (PR1 WHEN(FLOAT), PR2 WHEN(CHAR), PR3 WHEN(FLOAT, CHAR), PR4 WHEN(LABEL));
[edytuj] Przykład w języku Forth
Jeszcze inaczej przeciążanie funkcji (lub ogólniej indetyfikatorów) traktowane jest w języku Forth, co wynika ze specyfiki tego języka. W języku Forth definiujemy słowa (które mogą oznaczać podprogram, stałą, zmienną, słownik, kompilator (w sensie języka Forth)). Język umożliwia definiowanie słów w określonych słownikach. Dzięki temu można przeciążać nazwy lecz nie w obrębie pojedynczego słownika, ale w obrębie całej ( drzewiastej) struktury słowników, umieszacjąc słowa o tych samych nazwach w różnych słownikach. Zmieniając kolejność przeszukiwania słowników, wybierane będą różne podprogramy (z różnych słowników o tej samej nazwie).
Przykład:
VOC1 DEFINITIONS : OP-D DUP ROT DUP + ; VOC2 DEFINITIONS : OP-D DUP ROT DUP * ; VOC3 DEFINITIONS : OP-D DUP ROT DUP - ; VOC4 DEFINITIONS : OP-D DUP ROT DUP / ; ... 3 4 VOC1 OP-D . VOC2 OP-D .
Powyższy, trywanilny przykład definiuje podprogram OP-D, który w zależności od tego, kóry ze słowników VOC1, VOC2, VOC3, VOC4 będzie przeszukiwany w pierwszej kolejności wykona dodawanie, mnożenie, odejmowanie lub dzielenie, z zachowaniem argumentów operacji. Działenie powyzszyszych instrukcji spowouje wyprowadzenie liczby 7 (3+4), a następnie 12 (3*4).
[edytuj] Sytuacje niejednoznaczne i błędy przeciążania
Nie zawsze kompilator jest w stanie odpowiednio odróżnić funkcje o tej samej nazwie, muszą się one od siebie wyraźnie różnić. Czasem zdarzają się też sytuacje, w której dwie funkcje o tej samej nazwie mogą współistnieć, ale dane wywołanie byłoby niejednoznaczne. Problemy są następujące:
- Jeśli funkcje (jedna lub obie) przyjmują argumenty domyślne, to mogą współistnieć jeśli te "niedomyślne" argumenty mają te same typy, tyle że wywołanie z podaniem wyłącznie wymaganych argumentów będzie wtedy niejednoznaczne (i odrzucone). Najlepiej nie mieszać ze sobą przeciążania i argumentów domyślnych.
- Podczas wybierania funkcji do wywołania uwzględnia się też domyślne konwersje i trzeba znać ich priorytety; np. jeśli funkcję przeciążymy na typy short i long, to wywołanie z typem float jest niejednoznaczne.
- Przeciążać można tylko na podstawie typów argumentów (a nie wartości zwracanej).
- Uzyskanie wskaźnika do przeciążonej funkcji jest niemożliwe. Udaje się to tylko w przypadku wyrażeń, w których oczekuje się konkretnego typu od takiego wyrażenia, np. przypisując do zmiennej typu wskaźnika do funkcji - wtedy zostanie wybrana ta funkcja, która pasuje do sygnatury funkcji, do której jest ten wskaźnik. Nie można jednak takiej funkcji używać jako argumentu do szablonu funkcji - jest to znany problem z używaniem funkcji std::transform wraz z std::tolower.