150 likes | 372 Views
Programowanie obiektowe. Wykład 9. Programowanie obiektowe Szablony cz. II. Dariusz Wardowski. d r Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ. Programowanie obiektowe. Wykład 9. Parametry domyślne.
E N D
Programowanie obiektowe Wykład 9 Programowanie obiektowe Szablony cz. II Dariusz Wardowski dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Parametry domyślne Definiując szablon możemy dla danego parametru typu ustalić wartośćdomyślną, tzn. wartość, którą dany parametr osiągnie, gdy podczas konkretyzacji wartość typu zostanie pominięta. template <typename T1, typename T2 = char> class A { … }; Jeżeli podczas konkretyzacji szablonu A, nie wskażemy wartości dla parametru typu T2, zostanie użyty typ char. A<int,double> a1; //T1 = int, T2 = double A<char*> a2; //T1 = char*, T2 = char template <typename T = int> class B { … }; B<string> b1; // T = string B<> b2; // T = int dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Wartości domyślne w szablonach funkcji Definiując szablon klasy możemy korzystać zarówno z wartości domyślnych dla parametrów typu jaki i wartości domyślnych dla argumentów wyrażeń (nie-typów). Definiując szablon funkcji możemy używać wartości domyślne co najwyżej dla argumentów wyrażeń. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Niejawna konkretyzacja szablonów W przypadku, gdy na podstawie szablonu deklarujemy obiekt, określając żądany typ, korzystamy z niejawnej konkretyzacji szablonu. W takim przypadku kompilator uszczegóławia definicję klasy według schematu zadanego przez szablon tej klasy. A<int> a; niejawna konkretyzacja szablonu Ponadto kompilator zastosuje niejawną konkretyzację wówczas, gdy zostanie użyty obiekt konkretyzowanej klasy: A<int>* wsk; obiekt klasy jeszcze nie jest użyty, więc brak konkretyzacji wsk = newA<int>(); obiekt klasy A<int> jest tworzony, więc musi nastąpić konkretyzacja szablonu dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Jawna konkretyzacja szablonów Jawna konkretyzacja zachodzi wówczas, gdy podczas deklaracji klasy użyte jest słowo kluczowe template oraz podane są dokładne wartości typów. Definicja takiej klasy jest tworzona nawet jeśli nie tworzony jest obiekt tej klasy. Np.: templateclassA<double>; //możemy teraz korzystać z klasy A<double> dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Jawne uszczegółowienie szablonu Jawne uszczegółowienie polega na utworzeniu szablonu dla konkretnej wartości typu lub typów. Ma to zastosowanie w przypadku, gdy dla konkretnego typu chcemy zmienić działanie szablonu. template <typename T> classLiczbaTP { private: T x; public: LiczbaTP(T _x) : x(_x) {} T dodaj(LiczbaTP L); }; template <typename T> T LiczbaTP<T>::dodaj(LiczbaTP L) { return x + L.x; } dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Jawne uszczegółowienie szablonu c.d. template <> classLiczbaTP<char> { private: char x; public: LiczbaTP(char _x) : x(_x) {} char* dodaj(LiczbaTP L); boolczyWiekszaOd(constLiczbaTP L); }; char* LiczbaTP<char>::dodaj(LiczbaTP L) { char* trzy = new char[3]; trzy[0] = x; trzy[1] = L.x; trzy[2] = '\0'; return trzy; } LiczbaTP<int> L1(2), L1(5); //użyto definicji ogólnej szablonu cout << L1.dodaj(L2); //wypisze 7 LiczbaTP<char> C1(‘a’), C2(‘b’); //użyto definicji uszczegółowionej cout << C1.dodaj(C2); //wypisze „ab” dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Uszczegółowienie częściowe Stosując tego typu uszczegółowienie możemy skonkretyzować tylko niektóre parametry typu. Zatem definicja takiego szablonu tylko po części ulega ograniczeniu do konkretnego typu. template <typename T1, typename T2> class A { szablon ogólny … }; template <typename T2> class A<int,T2> { parametr T1 został uszczegółowiony … do parametru int }; template <> classA<int,int> { parametry T1, T2 zostały uszczegółowione … do parametru int }; A<char,char> a1; //użyto ogólny szablon A A<int,double> a2; //użyto częściowego uszczegółowienia A<int,T2> A<int,int> a3; //użyto jawnego uszczegółowienia A<int,int> dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Zagnieżdżanie szablonów W ramach definicji jednego szablonu dopuszczalne jest definiowanie wewnętrznego szablonu składowego. template <typename U> class Para { private: template <typename V> classElem { private: V x; public: Elem(V _x = 0) {x=_x;} V get() const {return V;} }; Elem<int> e1; Elem<U> e2; public: Para(U u, int i) : e1(i), e2(u) {} … }; dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Szablony a funkcje zaprzyjaźnione • Definiując szablon, możemy stosować funkcje zaprzyjaźnione. Możemy wtedy wyróżnić następujące przypadki: • Nieszablonowe funkcje zaprzyjaźnione, czyli takie, które nie są zależne od parametru typu. • Funkcje zaprzyjaźnione, których typ argumentów jest zależny od szablonu. • Funkcje zaprzyjaźnione szablonowe, ale takie, które nie są związane z szablonem. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Nieszablonowe funkcje zaprzyjaźnione template <typename T> class A { private: int x; public: A(); friendvoid f(); }; Funkcja f jest funkcją zaprzyjaźnioną z klasą będącą dowolną konkretyzacją szablonu A. Np. f jest zaprzyjaźniona z następującymi klasami: A<int>,A<double>,A<char*>,A<string>,A<bool>, … . W powyższej deklaracji funkcji f brak jest argumentów. Jaki jest zatem sens zaprzyjaźniać tego typu funkcje z klasą? dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Nieszablonowe funkcje zaprzyjaźnione z argumentami szablonowymi template <typename T> class A { private: int x; public: A(); friendvoid f(A &); }; źle!!! W celu przekazania do argumentu funkcji klasę szablonową, należy wskazać jej uszczegółowienie. friendvoid f(A<T> &); Ponieważ powyższa funkcja nie jest szablonowa, możemy zatem podać definicję tylko dla konkretnych typów. void f(A<int> & a) { cout << a.x + 1; } void f(A<char> & a) { cout << (int)a.x; } dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Szablonowe funkcje zaprzyjaźnione związane z szablonem W celu zdefiniowania szablonowej funkcji zaprzyjaźnionej związanej z szablonem należy w pierwszej kolejności przed definicją klasy ją zadeklarować. Następnie deklarujemy szablon wraz z wcześniej zadeklarowaną funkcją zaprzyjaźnioną. template <typename T> void f(T &); template <typename T> void g(); template <typename TYP> classPrzykladTP { private: TYP x; staticint i; public: friendvoidf<>(PrzykladTP<TYP> &); friendvoidg<TYP>(); }; template <typename T> int PrzykladTP<T>::i=0; template <typename T> void f(T & t) { cout << t.x; } template <typename T> void g() { cout << PrzykladTP<T>::i; } dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Szablonowe funkcje zaprzyjaźnione niezwiązane z szablonem To takie funkcje, których każde uszczegółowienie jest funkcją zaprzyjaźnioną dla każdego uszczegółowienia danej klasy. template <typename T> class A { private: T x; public: A(T _x) : x(_x) {} template <typename U> friendvoid f(U &); }; template <typename U> void f(U & u) { cout << u.x << endl; } intmain() { A<double> a1(2.3); A<char> a2(‘h’); f(a1); f(a2); return 0; } dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ
Programowanie obiektowe Wykład 9 Wesołych Świąt i Szczęśliwego Nowego Roku!!! dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ