15
Programowanie obiektowe Wykład 9 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15 Programowanie obiektowe Szablony cz. II Dariusz Wardowski

Programowanie obiektowe

  • Upload
    nicki

  • View
    50

  • Download
    5

Embed Size (px)

DESCRIPTION

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. - PowerPoint PPT Presentation

Citation preview

Page 1: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15

Programowanie obiektoweSzablony cz. II

Dariusz Wardowski

Page 2: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 2/15

Parametry domyślneDefiniują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 = doubleA<char*> a2; //T1 = char*, T2 = char

template <typename T = int>class B{…};

B<string> b1; // T = stringB<> b2; // T = int

Page 3: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 3/15

Wartości domyślne w szablonach funkcjiDefiniują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ń.

Page 4: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 4/15

Niejawna konkretyzacja szablonówW 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 konkretyzacjiwsk = new A<int>(); obiekt klasy A<int> jest tworzony, więc musi nastąpić konkretyzacja

szablonu

Page 5: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 5/15

Jawna konkretyzacja szablonówJawna 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.:

template class A<double>; //możemy teraz korzystać z klasy A<double>

Page 6: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 6/15

Jawne uszczegółowienie szablonuJawne 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>class LiczbaTP{ 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; }

Page 7: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 7/15

Jawne uszczegółowienie szablonu c.d.

template <> class LiczbaTP<char>{ private: char x; public: LiczbaTP(char _x) : x(_x) {} char* dodaj(LiczbaTP L); bool czyWiekszaOd(const LiczbaTP 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 szablonucout << L1.dodaj(L2); //wypisze 7

LiczbaTP<char> C1(‘a’), C2(‘b’); //użyto definicji uszczegółowionejcout << C1.dodaj(C2); //wypisze „ab”

Page 8: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 8/15

Uszczegółowienie częścioweStosują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};

A<char,char> a1; //użyto ogólny szablon AA<int,double> a2; //użyto częściowego uszczegółowienia A<int,T2>A<int,int> a3; //użyto jawnego uszczegółowienia A<int,int>

template <>class A<int,int>{ parametry T1, T2 zostały uszczegółowione … do parametru int};

Page 9: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 9/15

Zagnieżdżanie szablonówW ramach definicji jednego szablonu dopuszczalne jest definiowanie wewnętrznego szablonu składowego.

template <typename U>class Para{ private:

template <typename V>class Elem{ 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) {} …};

Page 10: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 10/15

Szablony a funkcje zaprzyjaźnioneDefiniują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.

Page 11: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 11/15

Nieszablonowe funkcje zaprzyjaźnionetemplate <typename T>class A{ private:

int x; public:

A();friend void 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ą?

Page 12: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 12/15

Nieszablonowe funkcje zaprzyjaźnione z argumentami szablonowymitemplate <typename T>class A{ private:

int x; public:

A();friend void f(A &);

};źle!!!

W celu przekazania do argumentu funkcji klasę szablonową, należy wskazać jej uszczegółowienie.

friend void 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;}

Page 13: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 13/15

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>class PrzykladTP{

private:TYP x;static int i;

public:friend void f<>(PrzykladTP<TYP> &);friend void g<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;}

Page 14: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 14/15

Szablonowe funkcje zaprzyjaźnione niezwiązane z szablonem

template <typename T>class A{ private: T x; public: A(T _x) : x(_x) {} template <typename U> friend void f(U &);};

template <typename U>void f(U & u){ cout << u.x << endl;}

To takie funkcje, których każde uszczegółowienie jest funkcją zaprzyjaźnioną dla każdego uszczegółowienia danej klasy.

int main(){ A<double> a1(2.3); A<char> a2(‘h’); f(a1); f(a2);

return 0;}

Page 15: Programowanie obiektowe

Programowanie obiektowe Wykład 9

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 15/15

Wesołych Świąt i Szczęśliwego Nowego Roku!!!