Šablony funkcí a tříd Šablony v C++ jsou vzory, podle kterých může překladač vytvářet celé skupiny podobných tříd či funkcí, které se liší jen v některých.

Slides:



Advertisements
Podobné prezentace
A1PRG - Programování – Seminář Ing. Michal Typová konverze, oblast platnosti, paměťové třídy 9 Verze
Advertisements

(instance konkrétní třídy)
Programování v C jazyku - SEMINÁŘ
Seminář C++ 5. cvičení Dědičnost Ing. Jan Mikulka.
Programovací jazyk C++
Programování funkcí v Excelu
Vnitřní řazení v poli (in sito)
10. Dynamické datové struktury
Pole, ukazatele a odkazy
ÚVOD DO CPP 7 Dědičnost - pokračování
BLIŽŠÍ POHLED NA TŘÍDY, DĚDIČNOST - úvod
Počítače a programování 1. Obsah přednášky Výjimky - základní typy výjimek Způsoby zpracování výjimek.
C++ Přednáška 3 Konstantní a statické členy tříd, ukazatel this, konstantní instance třídy Ing. Jiří Kulhánek , kat. 352, VŠB TU Ostrava 2004.
Preprocess Úvod do tvorby funkcí Princip preprocesoringu Direktivy preprocesoru Podmíněný překlad Základy tvorby funkcí Zjednodušený popis principu předávaní.
Programování v C++ Cvičení.
Programování v Pascalu Přednáška 7
Materiály k přednášce Úvod do programování Ondřej Čepek.
J a v a Začínáme programovat Lucie Žoltá metody, objekty, konstruktor.
Objekty v CLIPSu RNDr. Jiří Dvořák, CSc.
1 Vyhledávání Principy vyhledávání Klasifikace klíče:  Interní klíč – je součástí prohlížených záznamů  Externí klíč – není jeho součástí, je jím např.
Informatika I 3. přednáška
Páté cvičení Dědičnost Interface Abstarktní třídy a metody
Procedury a funkce Základní charakteristika a použití v programu.
Seminář C++ 9. cvičení Šablony Ing. Jan Mikulka. Šablony ► template – vzory, podle kterých může překladač tvořit skupiny podobných tříd nebo funkcí, které.
PB161 Jmenné prostory, I/O proudy PB161 | Jmenné prostory, IO proudy PB161 – Programování v jazyce C++ Objektově Orientované Programování.
Seminář C cvičení STL, Trolltech Ing. Jan Mikulka.
PB161 – Programování v jazyce C++ Objektově Orientované Programování
Objektové programování
Seminář C cvičení Obsluha výjimek Ing. Jan Mikulka.
6. cvičení Polymorfismus
A1PRG - Programování – Seminář Ing. Michal Ukazatele a pole 10 Verze
Počítače a programování 1
PB161 Právo friend, přetěžování operátorů, přetypování PB161 | Friend, operátory PB161 – Programování v jazyce C++ Objektově Orientované Programování.
JavaScript Podmínky, cykly a pole.
KIV/PPA1 cvičení 8 Cvičící: Pavel Bžoch. Osnova cvičení Objekty v Javě Třída Konstruktor Metody Metody a proměnné třídy x instance Program sestávající.
OSNOVA: a) Úvod do OOPb) Třídy bez metod c) Třídy s metodamid) Konstruktory a destruktory e) Metody constf) Knihovní třídy g) Třídy ve tříděh) Přetížení.
C# - předávání parametrů Centrum pro virtuální a moderní metody a formy vzdělávání na Obchodní akademii T.G. Masaryka, Kostelec nad Orlicí.
Návrh a tvorba WWW Přednáška 5 Úvod do jazyka PHP.
JavaScript Funkce.
Dědičnost - inheritance dědičnost je jednou z forem znovupoužitelnosti dědičnost je jednou z forem znovupoužitelnosti B A Třída A je předkem třídy B Třída.
7. Typ soubor Souborem dat běžně rozumíme uspořádanou množinu dat, uloženou mimo operační paměť počítače (na disku). Pascalský soubor je abstrakcí skutečného.
OSNOVA: a)Funkce – úvod b) Hlavičky funkcí c) Rekurze funkcí d)Knihovny funkcí e)Příklady Jiří Šebesta Ústav radioelektroniky, FEKT VUT v Brně Počítače.
Šesté cvičení Výjimky Balíky.
STRING A UKAZATELE. Co to je řetězec? Řetězec v Javě je samostatný objekt. Je konstantní, co znamená, že jednou vytvořený řetězec nelze změnit. Chceme-li.
Počítače a programování 1 7.přednáška. Základy Pole ve třídách a metodách Pole Arrays.
Pokročilé programování v C++ (část B)
Vazby dynamických proměnných,databázové systémy Přednáška č. 10.
Ukazatele, řetězce Přednáška č. 3. Ukazatele  Ukazatel (pointer) – typ o velikosti 4 bajty (v 32bit. systémech) pro uložení adresy objektu na který ukazuje.
Soubory BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky © Miroslav Balík Fakulta informačních technologií České vysoké.
Jazyk C A0B36PRI - PROGRAMOVÁNÍ Část II.
Vícerozměrná pole (1) Jazyk C povoluje, aby pole mělo více rozměrů (dimenzí) než jeden Z vícerozměrných polí bývá nejčastěji použí-váno pole dvourozměrné.
Podprogramy (subroutines) Pojmenované kousky programu, které –tvoří logicky ucelené části –se v programu opakují Jsou zapsány na jednom místě a v případě.
PROGRAMOVÁNÍ 3ITA,3ITB Jaroslav Burdys Hlavní zdroj:
Praha & EU: Investujeme do vaší budoucnosti Evropský sociální fond Gymnázium, Praha 10, Voděradská 2 Projekt OBZORY Datové typy a operátory Základní programové.
Programování OPERÁTOR SIZEOF, FUNKCE, POLE JAKO PARAMETRY FUNKCÍ ERIK KRÁL.
Programování v jazyce C++ Speciality jazyka C++, úvod do OOP.
Y36PJC Programování v jazyce C/C++
Programování ENUM, SWITCH,pole jednorozměrná a vícerozměrná, deklarace, inicializace, kopírování, porovnání Erik Král.
Vícerozměrná pole (1) Jazyk C povoluje, aby pole mělo více rozměrů (dimenzí) než jeden Z vícerozměrných polí bývá nejčastěji použí-váno pole dvourozměrné.
Programovací jazyk C++
Y36PJC Programování v jazyce C/C++
Programovací jazyk C Autorem materiálu a všech jeho částí, není-li uvedeno jinak, je Ing. Jitka Vlčková. Dostupné z Metodického portálu ISSN.
Programování 2. hodina RNDr. Jan Lánský, Ph.D.
Programování v jazyce C++
Dynamické proměnné (1) Proměnné, jejichž počet a (nebo) velikost pa-měti využívané těmito proměnnými se v prů-běhu programu mění Dynamické proměnné lze.
Oblast platnosti identifikátoru (1)
Opakování základních příkazů a syntaxí v programovacím jazyce Pascal
Programování v jazyce C++
C# přehled vlastností.
Funkce s proměnným počtem parametrů
Transkript prezentace:

Šablony funkcí a tříd Šablony v C++ jsou vzory, podle kterých může překladač vytvářet celé skupiny podobných tříd či funkcí, které se liší jen v některých datových typech nebo hodnotách konstant. Deklarace šablony : template deklarace; kde „deklarace“ může obsahovat běžnou deklaraci třídy nebo funkce. Šablona se uvádí klíčovým slovem template po němž následuje v závorkách <> seznam formálních parametrů šablony a pak deklarace dané třídy nebo funkce. Deklarace šablony končí středníkem. Instance šablony tvoříme implicitně (použitím) nebo explicitně, příkazem template instance; Parametry šablony mohou být hodnotové nebo typové, ty pak předepisujeme pomocí klíčového slova class nebo typename. Šablony se dají přirovnat k makrům v ANSI C – jedná se v podstatě o textové nahrazování formálních parametrů v těle šablony skutečnými parametry, vše se děje ještě na úrovni překladače

Šablony funkcí a tříd Příklady: Šablona třídy „Cosi“: template class Cosi { /* … */ }; Šablona funkce vracející větší z parametrů typu T: template T max( T x, T y) { return ( x > y ? x : y ); } Pomocí šablon se dají vytvořit tzv. generické třídy Použití šablony: za parametr šablony se dosadí konkrétní typ/hodnota Příklad: čítač pro různé datové typy template class Citac { T Hodn; … }; … Citac icitac(0) Citas zcitac(’A’) … int vi=iciatac.getValue(); int vz=zcitac.getValue();

Šablony funkcí a tříd Definice metod třídy Citac: template void Citac ::increment() { Hodn++; } template T Citac ::GetValue() { return Hodn; } Definice metod generické třídy musí opět začít generickou hlavičkou Tyto metody musí být uvedeny v hlavičkovém souboru Generická třída může být odvozena z abstraktní třídy Parametrem šablony může být i konstanta : template Příklad třídy pole: template class Pole { T slozky[D]; public : Pole(); Pole operator+(const Pole& p) const; T operator*( const Pole& p) const; Pole operator*(T s) const; friend Pole operator*(T s, const Pole& p); friend ostream& operator<<(ostream & o, const Pole& p); }

Šablony funkcí a tříd Pro každou velikost pole se vytvoří jiná definice třídy podle dané šablony. Nemusím tudíž brát ohled na různé velikosti polí při sčítání a násobení. Metoda součtu dvou polí : (musím si definovat =,+ a kopírující konstruktor) template Pole Pole::operator+(const Pole& p) const { Pole x; for (int i = 0; i < D; i++) { x.slozky[i] = slozky[i] + p.slozky[i]; } return x; } Příklad třídy pole: template class Pole { T slozky[D]; public : Pole(); Pole operator+(const Pole& p) const; T operator*( const Pole& p) const; Pole operator*(T s) const; friend Pole operator*(T s, const Pole& p); friend ostream& operator<<(ostream & o, const Pole& p); }

Vícenásobná dědičnost Pokud potřebuji aby potomek měl vlastnosti více předků Mohu předefinovávat metody předků. Všechny předky musím uvést v hlavičce. Př : class potomek : public predek1, public predek2, … { … }; Pokud předkové obsahují proměnné se stejným jménem pak dojde ke kolizi, musím k nim přistupovat pomocí specifikátoru rozsahu. Vícenásobnému zdědění položek se stejným jménem se dá zabránit pouze pomocí specifikace virtuální báze Př : metody vícenásobného dědění struct A { int a; }; struct B : A { int b; }; struct C : A { int c; }; struct A struct B struct C struct D : B, C {} Třída D obsahuje 2x složku a, jednou z třídy B podruhé z třídy C. dědění stejných položek lze zabránit pomocí virtuální báze - stejné položky se pak dědí jen jednou Př : struct B : virtual A { … }; struct C : virtual A { … }; struct D : A, B { … }; // teď je tam položka A::a jen jednou A::a B::bA::aC::c A::aB::bA::aC::c

Namespaces #include namespace RadimuvProstor { int secti(int a, int b); class Trida { private: int Atribut; public: void metoda(); }; void Trida::metoda() { cout << "Ahoj" << endl; } } int RadimuvProstor::secti(int a, int b) { return a + b; } slouží k odlišení názvů funkcí v rámci větších projektů pro přístup do určitého namespace se používá operátor :: nebo klíčové slovo „using“ implicitní – globální – namespace nemá žádné jméno, dá se na něj přistoupit např. takto: “::main()”

Výjimky mechanismu výjimek je definován k usnadnění ošetření chybových stavů v programu (např. dělení nulou, odkaz přes null pointer atd.) blok, ve kterém je riziko vzniku výjimky, se uzavře do bloku „try“ a ošetření výjimek se pak probíhá v navazujících blocích „catch“ Deklace metod, které mohou vyvolat výjimku, používá klíčová slovo „throw“ následované seznamem možných výjimek Pokud metoda v deklaraci nemá „throw“, znamená to, že může vyvolat jakoukoli výjimku (pozor, v Javě je to naopak – tam metoda bez „throw“ nevyvolává žádné výjimky!) Metoda může vyvolávat i více výjimek Třídy výjimek je vhodné tvořit v dědické hiearchii Opustí-li výjimka tělo naší funkce main, dojde k zavolání funkce terminate. Modifikace tohoto chování = pomocí funkce set_terminate. Funkce má jako parametr ukazatel na funkci, kterou má vyvolat volání funkce terminate. terminate i set_terminate jsou deklarovány v hlavičkovém souboru exception. Je-li z těla funkce nebo metody vyvržená výjimka, která není v seznamu výjimek, dojde k zavolání funkce unexpected. Tato funkce implicitně zavolá funkci terminate.Modifikace - funkce set_unexpected

Výjimky #include using namespace std; class Vyjimka { /* Třída výjimek */ private: string Duvod; public: void nastav(string d) { Duvod = d; } string dej() { return Duvod; } }; ostream &operator<< (ostream &os, Vyjimka &v) {return os << v.dej() << endl;} class Zlomek{ private: int C,J; public: void nastavCitatel(int c) { C = c;} void nastavJmenovatel(int j) {J = j;} double vydel() throw (Vyjimka); };

Výjimky double Zlomek::vydel() throw (Vyjimka) { // začátek bloku 2 int *i = new int; if (J == 0) { //začátek bloku 1 string s("Nejde"); Vyjimka v; v.nastav(s); throw v; } // konec bloku 1 delete i; return ((double)C / J); } // konec bloku 2 int main(void){ Zlomek z1,z2; z1.nastavCitatel(10); z2.nastavCitatel(5); for(int i = 5; i > -5; i--){ z1.nastavJmenovatel(i); z2.nastavJmenovatel(i); try{ cout << "10 / " << i << " = " << z1.vydel() << endl; cout << "5 / " << i << " = " << z2.vydel() << endl;} catch (Vyjimka v) { cout << v << endl; } catch (Jina_vyjimka j) {....} }return 0; }

Název kontejneru Typ kontejneru Hlavičkový soubor Popis kontejneru bitset posloupno st bitsetPosloupnost bitů pevné délky. deque posloupno st deque Oboustranná fronta. Prvky lze vkládat, nebo odebírat z obou konců. Sice lze rovněž odebírat, nebo vkládat prvky na libovolné místo ve frontě (kontejner deque to umožňuje), ale tato operace není příliš efektivní. list posloupno st listOboustranně zřetězený seznam. map asociativní kontejner map Asociativní pole. pole, které nemusí být indexováno celočíselným typem, ale čímkoliv. Třeba řetězcem. Pro daný klíč může existovat pouze 1 asociovaná hodnota. Tomuto kontejneru se budeme v budoucnu zabývat v samostatném článku. multimap asociativní kontejner map Asociativní pole. Pro daný klíč (index) může existovat více asociovaných hodnot. Tomuto kontejneru se budeme v budoucnu zabývat v samostatném článku. multiset asociativní kontejner set Multimnožina. množina, ve které se mohou prvky opakovat. Tomuto kontejneru se budeme věnovat později v samostatném článku. Knihovna STL

priority_ queue posloupnostqueue Prioritní fronta. Fronta, ve které neplatí pravidlo "první dovnitř, první ven". Prvky, které se do fronty uloží jsou uspořádány podle nějaké relace. Dalo by se říci, že předbíhají ve frontě podle nějaké předem dané priority. queueposloupnostqueue Klasické fronta. platí pravidlo, že prvek, který byl jako první vložen do fronty, z ní bude také první vybrán. set asociativní kontejner set Množina. Daná hodnota může být v množině obsažena jen jednou. Tomuto kontejneru se budeme věnovat později v samostatném článku. stackposloupnoststack Klasický zásobník. Platí pravidlo, že prvek, který byl vložen do zásobníku jako poslední bude vybrán jako první. vectorposloupnostvector Obdoba jednorozměrného pole. Tomuto kontejneru se budeme věnovat později v samostatném článku. Knihovna STL

Knihovna STL - bitset } #include int main( ) { // Using the default constructor using namespace std; bitset b0; cout b0 is: ( " b1 ( 6 ); cout b1( 6 ) is: ( " b2; cout b2 is: ( " b3 ( 6 ); cout b3( 6 ) is ( " b4 ( bitval4 ); cout b4( bitval4 ) is ( " b5 ( bitval5, 3, 6 ); cout b5( bitval, 3, 6 ) is ( " b6 ( bitval5, 3, 5 ); cout b6( bitval5, 3, 5 ) is ( " b7 ( bitval5, 2 ); cout b7( bitval, 2 ) is ( " << b7 << " )." << endl; } Output The set of bits in bitset b0 is: ( 00 ). The set of bits in bitset b1( 6 ) is: ( ). The set of bits in bitset b2 is: ( ). The set of bits in bitset b3( 6 ) is ( 110 ). The set of bits in bitset b4( bitval4 ) is ( ). The set of bits in bitset b5( bitval, 3, 6 ) is ( ). The set of bits in bitset b6( bitval5, 3, 5 ) is ( ). The set of bits in bitset b7( bitval, 2 ) is ( ).

Knihovna STL - bitset Erastotenovo síto čísla z rozsahu, ve kterém chceme zjistit všechna prvočísla, bereme jako prvky množiny kvůli paměťové efektivitě je pro množinu vhodné použít template bitset na začátku všechna čísla v množině označíme jako prvočísla (v množině bitset nastavíme bity na odpovídajících pozicích na true) pak ve smyčce bereme od nejmenšího všechna prvočísla, o kterých víme, že jsou prvočísla, (0 a 1 nebrat!) a „odznačujeme“ všechny jejich násobky v daném rozsahu tzn. postupně "prosíváme" množinu tak, že nakonec čísla složená (neprvočísla) zůstanou „pod sítem“ a prvočísla „nad sítem“. Prvocislo := 2; // zacnu od prvocisla 2 while 2 * Prvocislo <= Rozsah do begin Nasobek := 2 * Prvocislo; // prvni nasobek cisla Prvocislo while Nasobek <= Rozsah do begin ErastSito[Nasobek] := False; Nasobek := Nasobek + Prvocislo; end; repeat Prvocislo := Prvocislo + 1; // musim najit dalsi 100% prvocislo until (ErastSito[Prvocislo]) or (2 * Prvocislo > Rozsah); end;

Multiset // multiset_ctor.cpp // compile with: /EHsc #include #include int main( ) { using namespace std; multiset ::iterator ms1_Iter, ms2_Iter, ms3_Iter; multiset ::iterator ms4_Iter, ms5_Iter, ms6_Iter; // Create an empty multiset ms0 of key type integer multiset ms0; // Create an empty multiset ms1 with the key comparison // function of less than, then insert 4 elements multiset > ms1; ms1.insert( 10 ); ms1.insert( 20 ); ms1.insert( 20 ); ms1.insert( 40 ); // Create an empty multiset ms2 with the key comparison // function of geater than, then insert 2 elements multiset > ms2; ms2.insert( 10 ); ms2.insert( 20 ); // Create a multiset ms3 with the // allocator of multiset ms1 multiset ::allocator_type ms1_Alloc; ms1_Alloc = ms1.get_allocator( ); multiset ms3( less ( ), ms1_Alloc ); ms3.insert( 30 ); // Create a copy, multiset ms4, of multiset ms1 multiset ms4( ms1 ); // Create a multiset ms5 by copying the range ms1[_First, _Last) multiset ::const_iterator ms1_bcIter, ms1_ecIter; ms1_bcIter = ms1.begin( ); ms1_ecIter = ms1.begin( ); ms1_ecIter++; ms1_ecIter++; multiset ms5( ms1_bcIter, ms1_ecIter ); // Create a multiset ms6 by copying the range ms4[_First, _Last) // and with the allocator of multiset ms2 multiset ::allocator_type ms2_Alloc; ms2_Alloc = ms2.get_allocator( ); multiset ms6( ms4.begin( ), ++ms4.begin( ), less ( ), ms2_Alloc ); cout << "ms1 ="; for ( ms1_Iter = ms1.begin( ); ms1_Iter != ms1.end( ); ms1_Iter++ ) cout << " " << *ms1_Iter; cout << endl; cout << "ms2 = " << *ms2.begin( ) << " " << *++ms2.begin( ) << endl; cout << "ms3 ="; for ( ms3_Iter = ms3.begin( ); ms3_Iter != ms3.end( ); ms3_Iter++ ) cout << " " << *ms3_Iter; cout << endl; cout << "ms4 ="; for ( ms4_Iter = ms4.begin( ); ms4_Iter != ms4.end( ); ms4_Iter++ ) cout << " " << *ms4_Iter; cout << endl; cout << "ms5 ="; for ( ms5_Iter = ms5.begin( ); ms5_Iter != ms5.end( ); ms5_Iter++ ) cout << " " << *ms5_Iter; cout << endl; cout << "ms6 ="; for ( ms6_Iter = ms6.begin( ); ms6_Iter != ms6.end( ); ms6_Iter++ ) cout << " " << *ms6_Iter; cout << endl; } Output ms1 = ms2 = ms3 = 30 ms4 = ms5 = ms6 = 10 See Also

#include #include int main( ) { using namespace std; typedef pair Int_Pair; multimap ::iterator m1_Iter, m3_Iter, m4_Iter, m5_Iter, m6_Iter; multimap >::iterator m2_Iter; // Create an empty multimap m0 of key type integer multimap m0; // Create an empty multimap m1 with the key comparison // function of less than, then insert 4 elements multimap > m1; m1.insert( Int_Pair( 1, 10 ) ); m1.insert( Int_Pair( 2, 20 ) ); m1.insert( Int_Pair( 3, 30 ) ); m1.insert( Int_Pair( 4, 40 ) ); // Create an empty multimap m2 with the key comparison // function of geater than, then insert 2 elements multimap > m2; m2.insert( Int_Pair( 1, 10 ) ); m2.insert( Int_Pair( 2, 20 ) ); // Create a multimap m3 with the // allocator of multimap m1 multimap ::allocator_type m1_Alloc; m1_Alloc = m1.get_allocator( ); multimap m3( less ( ), m1_Alloc ); m3.insert( Int_Pair( 3, 30 ) ); // Create a copy, multimap m4, of multimap m1 multimap m4( m1 ); // Create a multimap m5 by copying the range m1[_First, _Last) multimap ::const_iterator m1_bcIter, m1_ecIter; m1_bcIter = m1.begin( ); m1_ecIter = m1.begin( ); m1_ecIter++; m1_ecIter++; multimap m5( m1_bcIter, m1_ecIter ); // Create a multimap m6 by copying the range m4[_First, _Last) // and with the allocator of multimap m2 multimap ::allocator_type m2_Alloc; m2_Alloc = m2.get_allocator( ); multimap m6(m4.begin( ), ++m4.begin( ), less ( ), m2_Alloc); cout second; cout second; cout second; cout second; cout second; cout second; cout << endl; } Output m1 = m2 = m3 = 30 m4 = m5 = m6 = 10 See Also

String #include #include using namespace std; int main(void) { string a = "Ahoj", b("svete"); string c,d; cout > d; cout << d; << endl; cout << "3. znak:" << c[2] << " z poctu:" << c.length() << endl; const char *stary = c.c_str(); cout << stary << endl; /* Nyní ukážu některé operátory */ if (a == b) { cout << "a == b" << endl; } if (a == string("Ahoj")) { cout << "a je Ahoj" << endl; a += string(" ctenari"); cout << a << endl; } return 0; }