Jazyk C++ I Šablony
AR 2013/2014
Jazyk C++ I
Úvod Zatím známe programovací styly: Strukturované programování, Objektově orientované programovaní.
AR 2013/2014
Jazyk C++ I
2
Příklady void Print(const int& value) { cout << value << endl; }
AR 2013/2014
Jazyk C++ I
3
Příklady void Print(const int& value) { cout << value << endl; } void Print(const string& value) { cout << value << endl; }
AR 2013/2014
Jazyk C++ I
4
Příklady void Print(const int& value) { cout << value << endl; } void Print(const string& value) { cout << value << endl; } void Print(const TA& value) { cout << value << endl; }
AR 2013/2014
Jazyk C++ I
5
Příklady class VectorInt { int* _values; //… };
AR 2013/2014
Jazyk C++ I
6
Příklady class VectorInt { int* _values; //… }; class VectorString { string* _values; //… };
AR 2013/2014
Jazyk C++ I
7
Příklady class VectorInt { int* _values; //… }; class VectorString { string* _values; //… }; class VectorTA { TA* _values; //… }; AR 2013/2014
Jazyk C++ I
8
Generické programování Programovací styl založený na vytváření abstraktních vzorů funkcí a tříd. Základem jsou zde šablony (templates).
AR 2013/2014
Jazyk C++ I
9
Šablony Šablony jsou podobné makrům v jazyce C. Zpracovávany překladačem. Umožňují najednou popsat celou řadu funkcí lišících se např. pouze typem parametru. Umožňují najednou popsat celou množinu tříd lišících se například jen datovým typem atributů.
AR 2013/2014
Jazyk C++ I
10
Šablony Představují vzory pro překladač, který podle ních vygeneruje konkrétní funkce nebo objektové typy. Hovoříme zde o instancích šablony.
AR 2013/2014
Jazyk C++ I
11
Příklad template
void Print(const T* value) { cout << value << endl; }
template class Vector { T* _values; //… };
AR 2013/2014
Jazyk C++ I
12
Deklarace šablony Šablony nelze deklarovat na lokální úrovni uvnitř bloku. Lze je deklarovat uvnitř objektového typu nebo uvnitř šablony objektového typu. Šablony také lze deklarovat na úrovni souboru. AR 2013/2014
Jazyk C++ I
13
Deklarace šablony Syntakticky korektní zápis deklarace šablony: template<parametersList> declaration parameterList – formální parametry šablony. declaration – deklarace nebo definice funkce nebo třídy, definice vnořené třídy, metody objektového typu, statického atributu šablony třídy nebo definice vnořené šablony. AR 2013/2014
Jazyk C++ I
14
Parametry šablony Syntakticky korektní zápis parametrů šablony je: • • • • • •
valueParameter class identifier class identifier = typeDesignation typename identifier typename identifier = typeDesignation template<parametersList> class identifier • template<parametersList> class identifier = templateName AR 2013/2014
Jazyk C++ I
15
Parametry šablony template class TA; template class TA { … }; // ok template class TB; template class TB { … }; // ok template class TC; template class TC { … }; // error AR 2013/2014
Jazyk C++ I
16
Parametry šablony
template class TA { … };
AR 2013/2014
Jazyk C++ I
17
Typové parametry Typové parametry lze uvést pomocí klíčových slov class a typename. Ekvivalentní
Skutečným parametrem je potom označení typu. Nesmí jim být ale lokální třída.
template class TA; template class TA; AR 2013/2014
Jazyk C++ I
18
Hodnotové parametry Deklarace obdobně jako u funkcí formální parametry. Hodnotový parametr musí být jedním z následujících typů:
Celočíselný Výčtový Ukazatel na objekt Reference na objekt Ukazatel na funkci Třídní ukazatel
Veškeré hodnotové parametry šablony se chovají jako konstanty. AR 2013/2014
Jazyk C++ I
19
Hodnotové parametry Celočíselný Skutečný parametrem je celočíselný konstantní výraz. template class TA { … }; TA<double, 10*5> A;
Výčtový Skutečným parametrem je celočíselný konstantní výraz, který má za výsledek daný výčtový typ. enum TB { b1, b2, b3 }; template class TA { … }; TA A; AR 2013/2014
Jazyk C++ I
20
Hodnotové parametry Ukazatel na objekt Skutečným parametrem je konstatní výraz, který představuje adresu pojmenovaného objektu s paměťovou třídou extern. Nelze použít adresu prvku pole.
Reference na objekt Skutečným parametrem je l-hodnota představující pojmenovaný objekt s paměťovou třídou extern. AR 2013/2014
Jazyk C++ I
21
Hodnotové parametry Ukazatel na funkci Skutečným parametrem je funkce s externím linkováním. template class TA { ... }; int f(int x) { ... } TA A;
Třídní ukazatel Skutečným parametrem je konstanta představující adresový výraz, který představuje adresu pojmenované složky třídy. struct TB { int x, y; } template class TA { ... }; TA A;
AR 2013/2014
Jazyk C++ I
22
Šablonové parametry
Název existující šablony třídy může být parametrem pro jinou šablonu.
AR 2013/2014
Jazyk C++ I
23
Šablonové parametry template class W> class TA { W a, b; public: TA(W _a, W _b) : a(_a), b(_b) {} }; template struct TB { T x, y; }; TB b1 = { 10, 20 }, b2 = { 30, 40 }; TA A(b1, b2); AR 2013/2014
Jazyk C++ I
24
Třídy Šablony pro objektové typy, tj. pro třídy, struktury nebo unie, může obsahovat stejné druhy složek jako objektový typ. Součástí šablony mohou být vložené, statické a virtuální metody, vnořené objektové typy apod.
AR 2013/2014
Jazyk C++ I
25
Třídy template class TVektor { T *a; int n; static int PocInstanci; public: TVektor(int _n = 0) : n(_n) { a = new T[n]; PocInstanci++; } ~TVektor() { delete[] a; PocInstanci--; } T& operator[](int index) { return a[index]; } bool operator == (const TVektor& t); static int GetPocInstanci() { return PocInstanci; } };
AR 2013/2014
Jazyk C++ I
26
Metody Jestliže metody nejsou definovány přímo v těle šablony, musí být definovány jako šablony. Šablona této metody potom musí obsahovat stejné formální parametry jako šablona její třídy, a to ve stejném pořadí. Jména formálních parametrů se potom mohou lišit. Jména metod musí být kvalifikována jmenovkou třídy, za kterou jsou v lomených závorkách jména formálních parametrů ve stejném pořadí. AR 2013/2014
Jazyk C++ I
27
Metody template struct TA { void f1(); void f2(); void f3(); void f4(); // … }; AR 2013/2014
Jazyk C++ I
28
Metody template void TA::f1() { … } // ok template void TA::f2() { … } // ok template void TA::f3() { … } // error
template void TA::f4() { … } // error
AR 2013/2014
Jazyk C++ I
29
Metody template bool TVektor::operator == (const TVektor& t) { if (n != t.n) return false; for (int i = 0; i < n; i++) { if (a[i] != t.a[i]) return false; } return true; } AR 2013/2014
Jazyk C++ I
30
Statické atributy Statické atributy je nutno definovat jako šablony. Šablony statického atributu se řídí stejnými pravidly jako šablony metod.
template class TVektor { … }; template int TVektor::PocInstanci = 0; AR 2013/2014
Jazyk C++ I
31
Vnořené třídy Vnořené třídy, které jsou definované mimo obklopující šablonu třídy, se musí definovat jako šablony. Opět se řídí stejnými pravidly jako šablony metod.
AR 2013/2014
Jazyk C++ I
32
Vnořené třídy template struct TA { struct TB; // … }; template struct TA::TB { T z; T& Pricti(T _z); }; template T& TA::TB::Pricti(T _z) { z += _z; return z; } TA::TB B; // instance of nested class
AR 2013/2014
Jazyk C++ I
33
Instance Dosazením skutečných parametrů namísto formálních v šabloně třídy vzniká instance šablony třídy podle této šablony. Jméno se pak skládá ze jména šablony a ze skutečných parametrů v lomených závorkách.
AR 2013/2014
Jazyk C++ I
34
Instance template class TA { … }; TA B; // ok TA A; // ok – TA TA<> C; // ok – TA TA D; // error
AR 2013/2014
Jazyk C++ I
35
Instance TVektor A(10), B(20); TVektor<double> C(10); TVektor< TVektor > D(10);
cout << TVektor::GetPocInstanci() << endl; cout << TVektor<double>::GetPocInstanci() << endl; AR 2013/2014
Jazyk C++ I
36
Instance Při vytváření instance šablony se generují virtuální metody instance šablony třídy. Překladač zároveň vytvoří ty instance metod a statických atributů, které jsou v programu použity. Pokud mají dvě instance šablony třídy skutečné parametry stejného typu, hodnotové parametry stejné hodnoty a šablonové typy se odkazují na stejnou šablonu, jsou tyto instance stejného typu. AR 2013/2014
Jazyk C++ I
37
Instance template struct TA { … }; typedef unsigned int uint; TA A; TA B; TA C; TA D; AR 2013/2014
Jazyk C++ I
38
Zdroje PRATA, Stephen. Mistrovství v C++. 3. aktualiz. vyd. Překlad Boris Sokol. Brno: Computer Press, 2007, 1119 s. ISBN 978-80-251-1749-1. cplusplus.com
AR 2013/2014
Jazyk C++ I
39