Wprowadzenie do szablonów – szablony funkcji
Transkrypt
Wprowadzenie do szablonów – szablony funkcji
Wprowadzenie do szablonów – szablony funkcji Bogdan Kreczmer ZPCiR IIAiR PWr pokój 307 budynek C3 [email protected] c 2006–2010 Bogdan Kreczmer? Copyright ° ? Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udostepniony ˛ pod warun- kiem wykorzystania wyłacznie ˛ do własnych prywatnych potrzeb i może on być kopiowany wyłacznie ˛ w całości, razem z niniejsza˛ strona˛ tytułowa. ˛ Separacja kodu i typów W jezykach ˛ takich jak C i Pascal mamy do czynienia z separacja˛ kodu i typu parametrów. Wartości z jakimi wywoływane sa˛ funkcje i procedury moga˛ parametryzować ich działanie. Jednak ich typy zostaja˛ ustalone raz na zawsze w momencie ich definicji. Problem: Należy zaimplementować algorytm sortowania dla obiektów różnych typów. Możliwe rozwiazania: ˛ • Implementacja algorytmu dla wszystkich typów, dla których przewidziane jest jego zastosowanie. • Implementacja algorytmu dla typu podstawowego takiego jak void∗ lub Object. • Zdefiniowanie makr i wykorzystanie specjalnych preprocesorów (np. cpp dla C/C++). Najlepszym rozwiazaniem ˛ dla postawionego problemu jest koncepcja szablonów. c 2006–2010 Bogdan Kreczmer Copyright ° Wprowadzenie do szablonów – szablony funkcji 1 Podstawowe cechy • Szablony pozwalaja˛ na definiowanie funkcji, których typy parametrów sa˛ także parametrami tych funkcji. • Możliwe jest definiowanie klas, które parametryzowane moga˛ być typami pól wystepuj ˛ acych ˛ w tych klasach i/lub też typami parametrów metod. • Programista definiuje tylko raz dany szablon. Kompilator dokonuje dedukcji typów parametrów danego szablonu i konkretyzuje go tworzac ˛ kod dla użytych typów w wywołaniu funkcji lub definicji obiektu danej klasy. • Programista może też jawnie określić “wartości” parametrów szablonu. c 2006–2010 Bogdan Kreczmer Copyright ° Wprowadzenie do szablonów – szablony funkcji 2 Podstawowe cechy Zalety: ? Szablony daja˛ możliwość tworzenia uniwersalnych algorytmów i uniwersalnych struktur danych. ? W odróżnieniu od makr możliwe jest zachowanie przejrzystości kodu. ? W odróżnieniu od wykorzystywania typów bazowych pozwalaja˛ zachować ścisła˛ kontrole˛ typów w trakcie kompilacji. Wady: ◦ Brak możliwości tworzenia oddzielnych jednostek kompilacji (modułów) w postaci “czystych” szablonów. c 2006–2010 Bogdan Kreczmer Copyright ° Wprowadzenie do szablonów – szablony funkcji 3 Szablon funkcji template <class Typ> Typ max( Typ w1, Typ w2 ) { return w1 < w2 ? w2 : w1; } enum Symbole { a=1, b, c }; int main( ) { cout << cout << cout << cout << } max(1,2) << endl; max(1.1, 2.2) << endl; max(’A’,’B’) << endl; max( a , b ) << endl; Wynik działania: 2 2.2 B 2 W tym przykładzie kompilator generuje kod funkcji max dla czterech przypadków. Słowo kluczowe class może zostać zastapione ˛ przez typename. c 2006–2010 Bogdan Kreczmer Copyright ° Wprowadzenie do szablonów – szablony funkcji 4 Szablon funkcji struct Wektor { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . float x, y; Wektor( float x = 0, float y = 0 ): x(x), y(y) { } bool operator < ( const Wektor& W ) const { return x∗ x+ y∗ y < W. x∗W. x+W. y∗W. y; } }; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . template < typename Typ > Typ max( Typ w1, Typ w2 ) { return w1 < w2 ? w2 : w1; } int main( ) { Wektor W1(1,1), W2(-2,1); W1 = max( W1, W2 ); cout << W1. x << ”, ” << W1. y << endl; } Wynik działania: -2, 1 Szablon funkcji można wykorzystywać dla własnych klas, o ile wszystkie realizowane w nim operacje bed ˛ a˛ legalne. c 2006–2010 Bogdan Kreczmer Copyright ° Wprowadzenie do szablonów – szablony funkcji 5 Szablon funkcji template <typename Typ> Typ max( Typ w1, Typ w2 ) { return cout << ”S: ”, w1 < w2 ? w2 : w1; } const char∗ max( const char∗ s1, const char∗ s2 ) { return cout << ”F: ”, std::strcmp(s1,s2) < 0 ? s2 : s1; } int main( ) { cout << max(”Abacki”,”Kowalski”) << endl; cout << max<const char∗>(”Abacki”, ”Kowalski”) << endl; cout << max<>(”Abacki”,”Kowalski”) << endl; Wynik działania: } F: Kowalski S: Abacki S: Abacki Funkcje zdefiniowane przez szablony moga˛ być przeciażone ˛ zwykłymi funkcjami. Można jednak wymusić użycie funkcji zdefiniowanej przez szablon. c 2006–2010 Bogdan Kreczmer Copyright ° Wprowadzenie do szablonów – szablony funkcji 6 Szablon funkcji template <typename Typ> Typ max( Typ w1, Typ w2 ) { return cout << ”S: ”, w1 < w2 ? w2 : w1; } template <> const char ∗ max<const char ∗>(const char ∗ s1, const char ∗ s2) { return cout << ”F: ”, std::strcmp(s1,s2) < 0 ? s2 : s1; } int main( ) { cout << max(”Abacki”,”Kowalski”) << endl; cout << max<const char∗>(”Abacki”, ”Kowalski”) << endl; cout << max<>(”Abacki”,”Kowalski”) << endl; Wynik działania: } F: Kowalski F: Kowalski F: Kowalski Można tworzyć specjalizacje˛ szablonu funkcji dla wybranego typu. c 2006–2010 Bogdan Kreczmer Copyright ° Wprowadzenie do szablonów – szablony funkcji 7