´ Uvod Jazyk Knihovny
´ r C++ Seminaˇ Petr Peringer peringer AT fit.vutbr.cz Vysoke´ uˇcen´ı technicke´ v Brneˇ Fakulta informaˇcn´ıch technologi´ı, ˇ Boˇzetechova 2, 61266 Brno
(Verze 2009-03-24)
´ r C++ ICP — Seminaˇ
1/211
´ Uvod Jazyk Knihovny
´ Uvod
ˇ ICP na FIT VUT v Brne. ˇ Tyto slajdy jsou urˇceny pro pˇredmet ´ Obsahuj´ı zakladn´ ı popis jazyka C++ vhodn´y pro studenty, kteˇr´ı ´ jazyk C. Obsah slajdu˚ je velmi struˇcn´y, podrobnejˇ ˇ s´ı jiˇz zvladli ´ ı v´ykladu. informace jsou souˇcast´
´ r C++ ICP — Seminaˇ
2/211
´ Uvod Jazyk Knihovny
Zdroje informac´ı
dobra´ literatura http://www.fit.vutbr.cz/study/courses/ICP/public/ WWW: FAQ, pˇrehledy knihoven ´ programu man (sekce 3) databaze GNU info a dalˇs´ı dokumentace ´ prostˇred´ı help v integrovanem
´ r C++ ICP — Seminaˇ
3/211
´ Uvod Jazyk Knihovny
Literatura
Stroustrup, B.: The C++ programming language, third edition, Addison-Wesley, 1997 ´ ı, dostupne´ na WWW Eckel, B.: Thinking in C++, 2. vydan´ http://www.ibiblio.org/pub/docs/books/eckel/ (existuje cˇ esk´y pˇreklad) ISO: Working Paper for Draft Proposed International Standard for Information Systems – Programming Language C++, December 1996 Booch, G.: Object-Oriented Design with applications, 2nd edition, The Benjamin/Cummings Publishing Company 1994
´ r C++ ICP — Seminaˇ
4/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Programovac´ı jazyk C++ Historie C C with classes ISO C90 ISO C++ ISO C99 ISO C++ ISO C++
(1973) (1981) (1990) (1998) (1999) (2004) (200x)
K&R = Kerninghan, Ritchie Bjarne Stroustrup, Bell Labs ´ mezinarodn´ ı norma jazyka C ´ mezinarodn´ ı norma C++ nova´ norma jazyka C aktualizace normy C++ nova´ verze normy C++
Puvodn´ ı definic´ı je kniha Stroustrup: The C++ Programming ˚ Language (Addison-Wesley 1985, 1991, 1997). Plat´ı norma ISO/IEC 14882 (1998). ´ a´ znalost jazyka ISO C ´ Poznamka: Tento text pˇredpoklad ´ r C++ ICP — Seminaˇ
5/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇrekladaˇce C++
Existuje cela´ ˇrada pˇrekladaˇcu˚ a v´yvojov´ych prostˇred´ı pro jazyk ´ ı pˇrehled najdete na WWW strance. ´ C++. Aktualn´ ˇ e´ prostˇred´ı Doporucen ˇ zne´ platformy. Je tˇreba GNU C++ existuje pro vˇsechny beˇ ˇ s´ı verzi, protoˇze ty starˇs´ı se pˇr´ıliˇs odchyluj´ı pouˇz´ıvat co nejnovejˇ od normy. ´ Poznamka: Integrovana´ prostˇred´ı, editory + program make
´ r C++ ICP — Seminaˇ
6/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Charakteristika jazyka C++ ˇ Obecneˇ vyuˇziteln´y programovac´ı jazyk vyˇssˇ ´ı urovn e. ´ Je standardizovan´y (ISO/ANSI) ´ ren´ı knihoven. Podporuje abstraktn´ı datove´ typy a vytvaˇ ´ ˇ a´ kompatibilita) Nastupce jazyka C (zpetn Efektivita ˇ cnost) Objektova´ orientace (tˇr´ıdy, dediˇ ˇ zovat operatory ´ Moˇznost pˇreteˇ Genericke´ tˇr´ıdy a funkce (ˇsablony) Obsluha v´yjimek Mnoho ruzn´ ˚ ych implementac´ı pˇrekladaˇcu˚ Mnoˇzstv´ı prostˇredku˚ pro ruzn ˚ e´ aplikace (GUI, ...)
´ r C++ ICP — Seminaˇ
7/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Nev´yhody C++
ˇ s´ı a sloˇzitejˇ ˇ s´ı neˇz C Je podstatneˇ vetˇ ˇ nekter ˇ ´ ´ ı pol´ı se Zdedil e´ problemy jazyka C (indexovan´ ´ ´ ˇ nekontroluje, manualn´ı sprava pameti, ...) Nen´ı cˇ isteˇ objektoveˇ orientovan´y (napˇr. typ int nen´ı tˇr´ıda a ˇ dedit) ˇ nelze z nej
´ r C++ ICP — Seminaˇ
8/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇreklad a sestaven´ı programu Soubor ahoj.cc: #include
int main() { std::cout << " Ahoj! \n"; }
// tisk ˇ retˇ ezce
´ ı (UNIX, pˇrekladaˇc GNU C++): Zpusob zpracovan´ ˚ g++ -o ahoj ahoj.cc ./ahoj
# pˇ reklad, sestaven´ ı # spuˇ stˇ en´ ı
´ Poznamka: Moˇzne´ pˇr´ıpony: .cc, .cpp, .C, .c++, .cxx ´ r C++ ICP — Seminaˇ
9/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ ı Optimalizace a laden´
´ Optimalizace kodu pˇrekladaˇcem (UNIX, GNU C++): g++ -O2 -o prog prog.cc ´ Poznamka: Nejlepˇs´ı urove nˇ optimalizace je tˇreba vyzkouˇset ´ ˇ ı (Linux, GNU C++, GNU debugger): Laden´ g++ -g -o prog prog.cc gdb prog ddd prog
´ r C++ ICP — Seminaˇ
# +ladic´ ı informace # ladˇ en´ ı na pˇ r´ ıkazov´ e ˇ r´ adce # ladˇ en´ ı v X11
10/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Pˇr´ıklad: cˇ ten´ı a tisk C++ ˇretezce #include #include <string>
// std::string
using namespace std;
// nemus´ ıme ps´ at std::
int main() { cout << "C++ string" << endl; string s; cout << "s = " << s << endl; cout << "string s (libovoln´ a d´ elka): " << flush; cin >> s ; // sledujte jak funguje (ˇ cte slova) cout << "s = " << s << endl; }
´ r C++ ICP — Seminaˇ
11/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ ´ Pˇr´ıklad: cˇ ten´ı a tisk C ˇretezce v C++ (nevhodne) ˇI ´VAT] // hroz´ ı chyba typu "buffer overflow" [NEPOUZ #include #include <string> using namespace std;
// nemus´ ıme ps´ at std::
int main() { cout << "C string" << endl; char s[100] = ""; cout << "s = " << s << endl; cout << "string s (max 99 zn): " << flush; cin >> s ; // ˇ cte slovo, pozor na "buffer overflow" cout << "s = " << s << endl; } ´ r C++ ICP — Seminaˇ
12/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: cˇ etnost slov #include #include <string> #include <map>
// kontejner std::map
typedef std::map<std::string,int> typedef map_t::iterator
map_t; mapiter_t;
int main() { std::string word; map_t m; // asociativn´ ı pole while( std::cin >> word ) // ˇ cte slova m[word]++; for(mapiter_t i=m.begin(); i!=m.end(); ++i) // tisk std::cout << i->first <<"\t"<< i->second <<"\n"; } ´ r C++ ICP — Seminaˇ
13/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: ˇrazen´ı cˇ ´ısel #include // cout #include // vector #include // sort, copy #include // ostream_iterator typedef std::vector vec_t; typedef std::ostream_iterator outiter_t; int main() { const int SIZE = 5; static int a[SIZE] = { 4, 2, 5, 1, 3 }; vec_t v(SIZE); // vektor std::copy(a, a+SIZE, v.begin() ); // kopie std::sort(v.begin(), v.end()); // ˇ razen´ ı outiter_t o(std::cout, "\n"); // iter´ ator std::copy(v.begin(), v.end(), o); // tisk } ´ r C++ ICP — Seminaˇ
14/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: ˇrazen´ı cˇ ´ısel — varianta 2 #include // vector #include // sort, copy #include // cout #include // ostream_iterator typedef std::vector vec_t; typedef std::ostream_iterator outiter_t; int main() { vec_t v; int i; while ( std::cin >> i ) // ˇ cten´ ı ˇ c´ ısel ze vstupu v.push_back(i); // vektor se zvˇ etˇ suje std::sort(v.begin(), v.end()); // ˇ razen´ ı outiter_t o(std::cout, "\n"); // iter´ ator std::copy(v.begin(), v.end(), o); // tisk } ´ r C++ ICP — Seminaˇ
15/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Rozd´ıly mezi C a C++
C++ je nadstavbou nad jazykem C90 ´ z C++ programy Dobˇre napsane´ C programy jsou teˇ ˇ (s nekolika v´yjimkami: nova´ kl´ıcˇ ova´ slova, povinne´ ˇ s´ı typova´ kontrola, ...) prototypy funkc´ı, silnejˇ ˇ pˇrekladaˇcem kromeˇ Rozd´ıly mezi C a C++ jsou zjiˇsteny ˇ nekolika v´yjimek: ´ jsou typu char Znakove´ literaly sizeof(’a’) == sizeof(int) // C sizeof(’a’) == sizeof(char) // C++
´ r C++ ICP — Seminaˇ
16/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
... V´ycˇ tov´y typ nen´ı ekvivalentn´ı typu int enum e { A }; sizeof(A) == sizeof(int) // C sizeof(A) == sizeof(e) // C++ != sizeof(int) ´ struktury v C++ muˇ ´ objektu, funkce, Jmeno ˚ ze pˇrekr´yt jmeno ´ bloku: v´ycˇ tu nebo typu v nadˇrazenem int x[99]; void f() { struct x { int a; }; sizeof(x); /* pole v C, struktura v C++ */ }
´ r C++ ICP — Seminaˇ
17/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Rozˇs´ıˇren´ı C++ proti C89 typ bool (true, false) typ reference inline funkce deklarace v bloku je pˇr´ıkaz anonymn´ı unie ˇ zovan´ ´ ı funkc´ı a operator ´ u˚ pˇreteˇ ´ operatory new, delete, new[] a delete[] tˇr´ıdy (class), abstraktn´ı tˇr´ıdy ´ ı dat (private, public, protected) ukr´yvan´ automaticka´ inicializace uˇzivatelem definovane´ konverze ´ ı funkce) polymorfismus (virtualn´
´ r C++ ICP — Seminaˇ
18/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı Rozˇs´ıˇren´ı C++98 proti C89 - pokraˇcovan´ ´ ´ jmeno tˇr´ıdy a v´ycˇ tu je jmeno typu ˇ cnost, nasobn ´ ˇ cnost dediˇ a´ dediˇ ukazatele na cˇ leny tˇr´ıd v inicializaci statick´ych objektu˚ je dovolen obecn´y v´yraz genericke´ datove´ typy – sˇ ablony (template, typename) obsluha v´yjimek (try, catch, throw) prostory jmen (namespace, using) ´ ı (static_cast, const_cast, nove´ zpusoby pˇretypovan´ ˚ reinterpret_cast, dynamic_cast) ˇ informace o typu za behu programu (typeid, type_info) kl´ıcˇ ove´ slovo mutable
´ r C++ ICP — Seminaˇ
19/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
C++
´ Poznamky /* text pozn´ amky */ // text pozn´ amky plat´ ı aˇ z do konce ˇ r´ adku ´ Identifikatory ´ Identifikatory obsahuj´ıc´ı dvojite´ podtrˇz´ıtko (__), nebo zaˇc´ınaj´ıc´ı podtrˇzen´ım a velk´ym p´ısmenem jsou vyhrazeny pro implementaci C++.
´ r C++ ICP — Seminaˇ
20/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Kl´ıcˇ ova´ slova C++ asm auto bool break case catch char class const const_cast continue default delete do double dynamic_cast ´ r C++ ICP — Seminaˇ
else enum explicit export extern false float for friend goto if inline int long mutable namespace
new operator private protected public register reinterpret_cast return short signed sizeof static static_cast struct switch template
this throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while 21/211
´ Uvod Jazyk Knihovny
Alternativn´ı reprezentace <% { and %> } bitand <: [ compl :> ] not_eq %: # or_eq %:%: ## xor_eq
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
&& & ~ != |= ^=
and_eq bitor not or xor
&= | ! || ^
´ Poznamka: Digraphs (<:), trigraphs (??/) // Provede se n´ asleduj´ ıc´ ı pˇ r´ ıkaz??/ i++;
´ r C++ ICP — Seminaˇ
22/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Literaly
´ u˚ je stejna´ jako v C. Syntaxe cˇ ´ıseln´ych literal ´ jsou typu: Znakove´ literaly char v C++ int
v C, v C++ pouze v´ıceznakove´ (mbc)
´ Poznamka: V C++ existuj´ı 3 ruzn ˚ e´ znakove´ typy: char, unsigned char a signed char Deklarace Deklarace muˇ ˚ ze b´yt kdekoliv mezi pˇr´ıkazy.
´ r C++ ICP — Seminaˇ
23/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Typova´ kontrola ˇ s´ı typova´ kontrola v C++ : Silnejˇ Deklarace: void (*func)(); je ukazatel na fci vracej´ıc´ı void v C, ukazatel na fci vracej´ıc´ı void bez parametru˚ v C++ Ukazatel na konstantn´ı objekt nelze pˇriˇradit do ukazatele na nekonstantn´ı objekt. ´ ı programu rozliˇs´ı funkce s Typova´ kontrola pˇri sestavovan´ ruzn´ ˚ ymi parametry V´ycˇ tov´y typ: ´ lze pˇriˇradit pouze konstantu daneho typu lze vynechat kl´ıcˇ ove´ slovo enum pˇri pouˇzit´ı ´ ´ ı na hodnotach ´ prvku˚ sizeof v´ycˇ toveho typu zavis´ ´ r C++ ICP — Seminaˇ
24/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ e´ cyklu ve for Rozsah deklarace promenn for(int i=1; i<10; i++) { /* zde plat´ ı i */ } ˇ (pozor na zastarale´ pˇrekladaˇce neodpov´ıdaj´ıc´ı norme: ´ BC3.1, ... a na star´y kod) Je chybou, kdyˇz je pˇr´ıkazem skoku pˇreskoˇcena inicializace ˇ e´ promenn
´ r C++ ICP — Seminaˇ
25/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Typ reference Definice: T & x = promˇ enn´ a_typu_T; bl´ızke´ ukazatelum ˚ (ale neexistuje obdoba NULL) ´ an´ ´ ı parametru˚ odkazem pouˇzitelne´ pro pˇredav nelze vytvoˇrit: referenci na referenci (pozn: C++0x), referenci na bitova´ pole, pole referenc´ı a ukazatele na reference.
V´yhodou referenc´ı je jednoduchost pouˇzit´ı (na rozd´ıl od *ptr) ´ Poznamka: C++0x: R-value reference: T && ´ r C++ ICP — Seminaˇ
26/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Typ reference – pˇr´ıklady double x = 1.23456; double & xref = x; // bˇ eˇ zn´ e pouˇ zit´ ı double & yref; extern int & zref;
// CHYBA! chyb´ ı inicializace // zde m˚ uz ˇe b´ yt bez inicializace
// pˇ red´ an´ ı parametru odkazem: void Transp(Matrix & m); // vracen´ ı reference: int & f(param); // POZOR na to CO se vrac´ ı! f(p) = 1;
´ r C++ ICP — Seminaˇ
// pouˇ zit´ ı funkce
27/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Reference — chybna´ nebo netypicka´ pouˇzit´ı const int & i = 7; // vytvoˇ r´ ı pomocnou promˇ ennou int & i = 7; // CHYBA! nelze pro nekonst. referenci float f = 3.14; const int & ir = f; // pomocn´ a_promˇ enn´ a = 3 ir = 5; // CHYBA! konstantu nelze zmˇ enit ´ Poznamka: Proˇc nelze pouˇz´ıt R-hodnotu s nekonstantn´ı referenc´ı: void incr( int& refint ) { refint++; } void g() { double d = 1; incr(d); // z´ aludn´ a chyba: nezmˇ en´ ı d ! } ´ r C++ ICP — Seminaˇ
28/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Typ bool ´ Booleovske´ literaly: false a true Implicitn´ı konverze bool ---> int true ---> 1 false ---> 0 Konverze cˇ ´ısel, v´ycˇ tu˚ a ukazatelu˚ na bool 0 ---> false jinak ---> true V´ysledek relaˇcn´ı operace je typu bool Pˇr´ıklad: bool test = false; test = (a > b); // bool test = 5; // int ---> bool ´ r C++ ICP — Seminaˇ
29/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operatory C++ maj´ı 16 urovn´ ı priorit ´ ´ operatory ( ) [ ] -> :: . ! ~ + - ++ -- & * (Typ) sizeof new delete .* ->* * / % + << >> < <= > >= == != & ^ | && || ?: = *= /= %= += -= &= ^= |= <<= >>= , ´ r C++ ICP — Seminaˇ
asociativita → ← → → → → → → → → → → → ← ← → 30/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operatory C++ ´ operator :: .* ->* new delete static_cast, reinterpret_cast, const_cast, dynamic_cast
´ r C++ ICP — Seminaˇ
popis ´ kvalifikator dereference ukazatele na cˇ len tˇr´ıdy pˇres objekt dereference ukazatele na cˇ len tˇr´ıdy pˇres ukazatel na objekt dynamicke´ vytvoˇren´ı objektu zruˇsen´ı objektu ´ ´ ı nove´ operatory pˇretypovan´
31/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operatory — pˇr´ıklady // alokace pamˇ eti oper´ atorem new: T *p = new T[10*n]; // dynamick´ a alokace pole T *p2 = new T(5); // dynamick´ a alokace objektu // uvolnˇ en´ ı pamˇ eti oper´ atorem delete: delete [] p; // uvolnˇ en´ ı pamˇ eti pole delete p2; // uvolnˇ en´ ı pamˇ eti objektu // alokace a ruˇ sen´ ı pole bajt˚ u: char *s = new char[100]; delete [] s; // char *s2 = static_cast(std::malloc(100)); // std::free(s2);
´ r C++ ICP — Seminaˇ
32/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator :: ´ ı promenn ˇ e: ´ Pˇr´ıstup ke globaln´ double x; void f() { int x; // lok´ aln´ ı x ::x = 3.1415926; // glob´ aln´ ı x } Explicitn´ı specifikace tˇr´ıdy: class T { public: int metoda(); // deklarace metody }; int T::metoda() { } // definice mimo tˇ r´ ıdu Specifikace prostoru jmen: prostor::identifik´ ator std::cin prostor::podprostor::identifik´ ator ´ r C++ ICP — Seminaˇ
33/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Standardn´ı konverze v C++ I ´ pˇri Implicitn´ı konverze prob´ıhaj´ı automaticky (jsou-li nutne) ´ ı binarn´ ´ ıch operac´ı: vyhodnocovan´ 1
Kaˇzd´y ’mal´y’ celoˇc´ıseln´y typ se konvertuje takto: typ konverze na metoda char int podle nastaven´ı unsigned char int dopln´ı nuly ´ signed char int rozˇs´ıˇr´ı znamenko short int stejna´ hodnota unsigned short unsigned int stejna´ hodnota enum int stejna´ hodnota bool int 0 nebo 1 Potom je kaˇzda´ hodnota operandu budˇ int (vˇcetneˇ long a ´ u) unsigned modifikator ˚ double, float nebo long double.
2
ˇ ´ Je-li nekter´ y operand long double, je druh´y konvertovan na long double
´ r C++ ICP — Seminaˇ
34/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Standardn´ı konverze v C++ II
3
Jinak, je-li operand double, konvertuje druh´y na double
4
Jinak, je-li operand float, konvertuje druh´y na float
5
Jinak, je-li operand unsigned long, konvertuje druh´y na unsigned long
6
Jinak, je-li operand long, konvertuje druh´y na long
7
Jinak, je-li operand unsigned, konvertuje druh´y na unsigned
8
Jinak, jsou oba operandy typu int
V´ysledek odpov´ıda´ typu obou operandu˚ po konverzi.
´ r C++ ICP — Seminaˇ
35/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Konverze — pˇr´ıklady
´ Poznamka: ´ an´ ´ ı cˇ ´ısla int s cˇ ´ıslem unsigned muˇ Pˇri porovnav ˚ ze doj´ıt k (pro ˇ ´ ´ um: nekoho neoˇcekavan´ ym) problem ˚ int i = -1; unsigned u = 1234; if(i
´ r C++ ICP — Seminaˇ
// sledujte varov´ an´ ı pˇ rekladaˇ ce // nevytiskne nic!
36/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Explicitn´ı konverze ´ ı programator ´ Explicitn´ı konverze uvad´ do textu programu ˇ (a pˇreb´ıra´ za neˇ veˇskerou odpovednost): (typ) v´ yraz typ(v´ yraz) static_cast(v´ yraz) Pˇr´ıklady:
´ ı Explicitn´ı pˇretypovan´
double(int1)/int2 complex(3.14) int(’c’) static_cast(ptr) reinterpret_cast(ptr)
´ r C++ ICP — Seminaˇ
37/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
extern "C" Moˇznost pouˇzit´ı funkc´ı z knihoven jazyka C, pˇr´ıpadneˇ jin´ych jazyku: ˚ extern "C" int f(int); extern "C" { int g(int); int h(int); }
´ Poznamka: Prostory jmen
´ r C++ ICP — Seminaˇ
38/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Preprocesor ´ ı Je stejn´y jako v ISO C, je vhodne´ minimalizovat jeho pouˇz´ıvan´ ´ (protoˇze mame lepˇs´ı prostˇredky): lze nahradit za:
#define K1 10 const int K1 = 10; #define f(x)
(v´ yraz_x)
ˇ sinou nahradit za: lze vetˇ
inline int f(int x) { return v´ yraz_x; } pˇr´ıpadneˇ lze pouˇz´ıt genericke´ funkce: template inline T f(T x) { return v´ yraz_x; }
´ r C++ ICP — Seminaˇ
39/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Zakladn´ ı principy OO pˇr´ıstupu
Tradiˇcn´ı pˇr´ıstup program = data + algoritmy(podprogramy) ´ ı pˇr´ıstup Modularn´ program = moduly modul = data + algoritmy(podprogramy) Objektoveˇ orientovan´y pˇr´ıstup program = objekty + komunikace ˇ e´ tˇr´ıdy (klasifikace) kaˇzd´y objekt patˇr´ı do nejak ´ an´ ´ ı) hierarchie objektu˚ (sklad ˇ cnost) hierarchie tˇr´ıd (dediˇ
´ r C++ ICP — Seminaˇ
40/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
V´yvoj programu˚ ´ ´ ı – udrˇ anal´yza – navrh – implementace – testovan´ ´ zba Objektoveˇ orientovana´ anal´yza (OOA) ´ ı poˇzadavku˚ z hlediska tˇr´ıd a objektu˚ zkouman´
´ Objektoveˇ orientovan´y navrh (OOD) dekompozice ´ popis systemu a jeho charakteristik notace (grafy)
´ ı (OOP) Objektoveˇ orientovane´ programovan´ program je skupina spolupracuj´ıc´ıch objektu˚ ˇ e´ tˇr´ıdy kaˇzd´y objekt reprezentuje instanci nejak ´ ˇ cnosti tˇr´ıdy jsou navzajem v relaci dediˇ volba implementaˇcn´ıho jazyka
´ r C++ ICP — Seminaˇ
41/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Objektov´y model Hlavn´ı principy Abstrakce Zapouzdˇren´ı Modularita (fyz.) Hierarchie
Vedlejˇs´ı principy ´ ı typovan´ paralelismus persistence
´ Poznamky: tyto principy nejsou nove´ ˇ cnost = hierarchie abstrakc´ı dediˇ
´ r C++ ICP — Seminaˇ
42/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Notace
Pouˇzit´ı grafu: ˚ diagramy tˇr´ıd diagramy objektu˚ diagramy komunikace objektu˚ ´ Poznamka: UML
´ r C++ ICP — Seminaˇ
43/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Tˇr´ıdy tˇ r´ ıda = data + funkce + zapouzdˇ ren´ ı ´ Rozˇs´ıˇren´ı systemu typu˚ — reprezentuje mnoˇzinu objektu˚ ´ ı objektu˚ Definuje rozhran´ı a chovan´ Kl´ıcˇ ova´ slova: class, struct a union C++ povoluje nekompletn´ı deklarace tˇr´ıd: class X; // => omezen´ ı pˇ ri pouˇ zit´ ı Pˇr´ıklad: Tˇr´ıda T class T { int i; // data (i jin´ e objekty) public: // specifikace pˇ r´ ıstupov´ ych pr´ av void m(); // metody typedef int typ; // vnoˇ ren´ e typy, atd. }; ´ r C++ ICP — Seminaˇ
44/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Tˇr´ıdy a objekty — pˇr´ıklad
Pˇr´ıklad: Objekty tˇr´ıdy T T x; T &refx = x; T *ptrx = &x; T xarr[20];
// // // //
objekt tˇ r´ ıdy T reference na objekt tˇ r´ ıdy T ukazatel na objekt tˇ r´ ıdy T pole objekt˚ u tˇ r´ ıdy T
´ tˇr´ıdy je stejn´y jako u struktur ´ Poznamka: Pˇr´ıstup ke sloˇzkam
´ r C++ ICP — Seminaˇ
45/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Datove´ cˇ leny a vnoˇrene´ objekty Datove´ sloˇzky tˇr´ıdy ˇ zne´ datove´ sloˇzky (jsou v kaˇzdem ´ objektu) Beˇ Staticke´ datove´ sloˇzky pouze jedna instance pro jednu tˇr´ıdu (tj. vˇsechny objekty tˇr´ıdy sd´ıl´ı tuto instanci) ´ y objekt jsou pˇr´ıstupne´ i kdyˇz neexistuje zˇ adn´ mus´ı se definovat a inicializovat vneˇ definice tˇr´ıdy (kromeˇ konstant)
Pouˇzit´ı statick´ych datov´ych sloˇzek: Spoleˇcn´y bank pro vˇsechny objekty (napˇr. poˇcet vytvoˇren´ych objektu˚ dane´ tˇr´ıdy) ´ en ˇ emu ´ Zapouzdˇren´ı — ochrana proti neopravn pˇr´ıstupu
´ r C++ ICP — Seminaˇ
46/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Datove´ cˇ leny a vnoˇrene´ objekty — pˇr´ıklad Pˇr´ıklad ruzn´ ˚ ych datov´ych sloˇzek tˇr´ıdy class X { static const int N = 100; // konstanta static int count; // jedna instance pro tˇ r´ ıdu int i; // je v kaˇ zd´ em objektu string s; // v kaˇ zd´ em objektu double data[3]; // v kaˇ zd´ em objektu }; int X::count = 0; // Pozor! je nutn´ a definice v modulu
´ Poznamka: C++0x: inicializace sloˇzek — napˇr. int i=5; ´ r C++ ICP — Seminaˇ
47/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Kontrola pˇr´ıstupu ke cˇ lenum ˚ tˇr´ıd Specifikace pˇr´ıstupu public private protected
muˇ ˚ ze b´yt pouˇzit libovolnou funkc´ı pouze pro metody a friend funkce dane´ tˇr´ıdy ´ jako private, ale nav´ıc je dostupne´ v metodach ´ tˇr´ıdy a friend funkc´ıch tˇr´ıd odvozen´ych z teto
Implicitn´ı nastaven´ı: pro definici class struct union
´ r C++ ICP — Seminaˇ
implicitneˇ plat´ı private public public
lze pˇredefinovat ano ano ne
48/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Kontrola pˇr´ıstupu ke cˇ lenum ˚ tˇr´ıd — pˇr´ıklad ˇ libovolne: ˇ Pˇr´ıstupove´ specifikace mohou b´yt um´ısteny class T { int i; // public: int j; // protected: int k; // public: int l; // int m; private: int n; };
´ r C++ ICP — Seminaˇ
class => implicitnˇ e private public protected public
49/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Friend funkce a tˇr´ıdy
kl´ıcˇ ove´ slovo friend ´ pˇr´ıstupu ke vˇsem cˇ lenum maj´ı plna´ prava ˚ tˇr´ıdy ˇ ı vlastnost friend se neded´ vlastnost friend nen´ı tranzitivn´ı ´ Poznamky: pouˇz´ıvat jen v´yjimeˇcneˇ naruˇsuje ochranu dat ´ ren´ı mnoˇzin pˇr´ıbuzn´ych tˇr´ıd (napˇr´ıklad pouˇzitelne´ pro vytvaˇ ´ kontejner + iterator)
´ r C++ ICP — Seminaˇ
50/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Friend funkce a tˇr´ıdy — pˇr´ıklad class Y; // class X { int data; // friend Y; // friend int f(X*);// }; class Y { // void m(X &o) { o->data = 0; // } }; int f(X *ptr) { ptr->data = 1; } ´ r C++ ICP — Seminaˇ
nekompletn´ ı deklarace tˇ r´ ıdy Y priv´ atn´ ı data friend tˇ r´ ıda Y deklarace friend funkce definice tˇ r´ ıdy Y pˇ r´ ıstup je moˇ zn´ y
// pˇ r´ ıstup je moˇ zn´ y
51/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Metody
Kategorie metod Konstruktory (vznik objektu) ´ Destruktory (zanik objektu) Staticke´ metody ˇ zne´ metody (ne staticke) ´ Beˇ ´ ı metody (polymorfismus) Virtualn´ ´ Operatory (ruzn ˚ e´ operace: + - * /) ´ ı objektu na jin´y typ) Konverze (pˇretypovan´
´ r C++ ICP — Seminaˇ
52/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Inline metody optimalizace rychlosti programu ´ e´ funkce (jinak ”code bloat”) vhodne´ pro kratk metoda definovana´ uvnitˇr tˇr´ıdy je automaticky inline: class X { char *i; public: char *f() { // implicitnˇ e inline return i; } }; ´ s explicitn´ım uveden´ım kl´ıcˇ oveho slova inline: inline char *X::f() { return i; }
´ r C++ ICP — Seminaˇ
53/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Jednoduch´y pˇr´ıklad: tˇr´ıda interval // tˇ r´ ıda ˇ c´ ısel od jedn´ e do deseti class Int_1_10 { int n; public: Int_1_10() { n = 1; } // implicitn´ ı ctr Int_1_10(int n) { SetValue(n); } void SetValue(int x); // deklarace metody int GetValue() { return n; } void Print(); }; void Int_1_10::SetValue(int x) { // definice metody if(x<1 || x>10) error("Range error"); n = x; } ´ r C++ ICP — Seminaˇ
54/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Kl´ıcˇ ove´ slovo this
implicitn´ı parametr nestatick´ych metod tˇr´ıdy ukazatel na objekt se kter´ym metoda pracuje pro metodu tˇr´ıdy T je this typu T *const nebo const T *const pro konstantn´ı objekty ´ se ve specialn´ ´ ıch pˇr´ıpadech mus´ı pouˇz´ıvat v sˇ ablonach this->ˇ clen lze pouˇz´ıt pouze uvnitˇr nestaticke´ metody, napˇr´ıklad pro ´ ı odkazu na objekt pˇredan´
´ r C++ ICP — Seminaˇ
55/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad pouˇzit´ı this class T { public: void f() { std::cout << "T\n"; } void f() const { std::cout << "const T\n"; } T clone() const { return *this; } }; T o1; const T o2 = T();
// nekonstantn´ ı objekt // konstantn´ ı objekt
int main() { o1.f(); // T *const this = &o1 o2.f(); // const T *const this = &o2 T o = o1.clone(); } ´ r C++ ICP — Seminaˇ
56/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Staticke´ metody
nemaj´ı this ´ ı nesm´ı b´yt virtualn´ chovaj´ı se jako obyˇcejne´ funkce, ale maj´ı pˇr´ıstup k private ´ tˇr´ıdy sloˇzkam pouˇzit´ı mimo metody tˇr´ıdy se mus´ı kvalifikovat T::staticka_metoda(parametry) ´ y objekt lze je volat i kdyˇz neexistuje zˇ adn´ vhodne´ po pomocne´ funkce pro tˇr´ıdu
´ r C++ ICP — Seminaˇ
57/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Staticke´ metody — pˇr´ıklad class X { static int count; // toto nen´ ı definice! public: static int getCount(); // vrac´ ı poˇ cet objekt˚ u static void func(int i, X* ptr); // nevhodn´ e? void g(); }; int X::count = 0;
// definice a inicializace
void g() { int i = X::getCount(); X obj; X::func(1, &obj); obj.g(); }
// // // //
´ r C++ ICP — Seminaˇ
nepotˇ rebuje objekt definice objektu tˇ r´ ıdy objekt pˇ red´ an explicitnˇ e obyˇ cejn´ a metoda 58/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Vnoˇrene´ typy
typy deklarovane´ uvnitˇr tˇr´ıdy vnoˇrena´ tˇr´ıda (”nested class”) typedef
souvislost s prostory jmen lze pouˇz´ıt neupln ´ e´ deklarace vnoˇrene´ tˇr´ıdy ´ pouˇzit´ı pro ukryt´ı implementaˇcneˇ zavisl´ ych tˇr´ıd (napˇr´ıklad ´ iteratory v kontejnerech)
´ r C++ ICP — Seminaˇ
59/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Vnoˇrene´ typy — pˇr´ıklad struct A { typedef int MujTyp; struct B { void MetodaB(int); }; class C; }; class A::C { }; void A::B::MetodaB(int int main() { A::B obj; A::MujTyp i = 5; obj.MetodaB(i); } ´ r C++ ICP — Seminaˇ
// vnoˇ ren´ y typ // definice vnoˇ ren´ e tˇ r´ ıdy // deklarace metody // deklarace vnoˇ ren´ e tˇ r´ ıdy C // definice C mimo tˇ r´ ıdu A i) { } // definice metody
// B je public
60/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operatory new a delete ˇ ı dynamicke´ vytvaˇ ´ ren´ı a ruˇsen´ı Umoˇznuj´ jednotliv´ych objektu˚ (new, delete) pol´ı objektu˚ (new[], delete[]) Lze je pˇredefinovat, pˇr´ıpadneˇ pˇret´ızˇ it (vhodne´ napˇr´ıklad pro ´ ˇ pouˇzit´ı s jinou spravou volne´ pameti). Alokace objektu˚ new T 1 alokuje pameˇ ˇt pro objekt pouˇzije T::operator new(), pokud existuje jinak pouˇzije ::operator new() 2
operator new pˇri chybeˇ vyvola´ v´yjimku bad_alloc ˇ sne´ alokaci je vyvolan ´ konstruktor po usp ´ eˇ
Pˇr´ıklad: ´ r C++ ICP — Seminaˇ
ukazatel = new complex; 61/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Alokace pol´ı new T[velikost] 1 alokuje pameˇ ˇt pro pole ´ pouˇzije T::operator new[](), pokud je definovan nen´ı-li pouˇzije ::operator new[]() 2
pˇri chybeˇ vyvola´ v´yjimku bad_alloc vola´ se implicitn´ı konstruktor na kaˇzd´y prvek pole v rostouc´ım poˇrad´ı indexu˚
ˇ pole. Prvn´ı ´ Poznamka: Mus´ı b´yt uvedeny vˇsechny rozmery ˇ nemus´ı b´yt konstantn´ı v´yraz. rozmer Pˇr´ıklad: T *pt = new T[10]; // pole 10 objekt˚ u ´ r C++ ICP — Seminaˇ
62/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator delete ˇ ı pameti ˇ Uvolnen´ delete ptr delete[] ptr 1 ´ ´ poˇrad´ı neˇz pˇri new vola´ destruktory v obracen em 2 ´ ım T::operator delete() nebo uvoln´ı pameˇ ˇt volan´ ::operator delete() (pˇr´ıpadneˇ varianta s delete[] pro pole) Pˇr´ıklady: delete ukazatel; // ruˇ s´ ı objekt alokovan´ y new T delete [] ptr; // ruˇ sı ´ pole alokovan´ e new T[n]
´ r C++ ICP — Seminaˇ
63/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı alokace pameti ˇ Specialn´ ´ ˇ Operator new (nekdy i delete) muˇ ˚ ze m´ıt v´ıce parametru. ˚ ´ ı adresu. Toho se vyuˇz´ıva´ napˇr´ıklad pro alokaci na konkretn´ new mus´ı m´ıt prvn´ı parametr typu size_t delete mus´ı m´ıt prvn´ı parametr typu void* ´ ı operatoru ´ Pˇr´ıklady volan´ new new T vol´ a operator new(sizeof(T)) new(adr) T operator new(sizeof(T),adr) new T[5] operator new[](sizeof(T)*5 + x) new(22) T[5] operator new[](sizeof(T)*5 + y, 22) ( x a y jsou implementac´ı definovane´ hodnoty )
´ r C++ ICP — Seminaˇ
64/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı alokace pameti ˇ 2 Specialn´ ´ Identifikator nothrow oznaˇcuje objekt tˇr´ıdy, pro kterou je ´ ´ ı pˇret´ızˇ ena´ varianta operatoru ´ definovana specialn´ new vracej´ıc´ı ´ ı v´yjimky bad_alloc) pˇri nedostatku 0 (NULL) (m´ısto vyvolan´ ˇ pameti. ´ Pouˇzitelne´ pro embedded systemy, kde je reˇzie v´yjimek ´ neˇzadouc´ ı. Pˇr´ıklad: Pouˇzit´ı nothrow T *p = new(nothrow) T; if( p==0 ) errorexit("m´ alo pamˇ eti"); // ... delete p;
´ r C++ ICP — Seminaˇ
65/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Definice new a delete pro tˇr´ıdu
Pro tˇr´ıdu T lze definovat funkce: void * T::operator new(size_t); void * T::operator new[](size_t);
// jeden objekt // pole objekt˚ u
void T::operator delete(void* ptr); void T::operator delete[](void* ptr); ´ Nejsou-li v´ysˇ e uvedene´ operace definovany, pouˇzij´ı se ´ standardn´ı operatory.
´ r C++ ICP — Seminaˇ
66/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı alokace objektu˚ tˇr´ıdy — pˇr´ıklad Specialn´ class T { public: void * operator new (size_t s); void operator delete (void* ptr); }; void * T::operator new (size_t s) { char* ptr = new char[s]; // vol´ a //=== ZDE m˚ uˇ zeme prov´ est potˇ rebn´ e return static_cast(ptr); } void T::operator delete (void* ptr) //=== ZDE m˚ uˇ zeme prov´ est potˇ rebn´ e delete[] static_cast(ptr); } ´ r C++ ICP — Seminaˇ
standardn´ ı new operace ...
{ operace ... // ::delete
67/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Konstruktory
´ ı metody pro inicializaci objektu˚ pˇri vzniku specialn´ ˇ zovan´ ´ ı funkc´ı) lze definovat v´ıce konstruktoru˚ (viz. pˇreteˇ ´ automaticky pˇri vytvaˇ ´ ren´ı objektu˚ jsou volany nesm´ı b´yt static ani virtual lze je volat na const a volatile objekty ´ ´ ren´ı objektu˚ specifikac´ı private lze zakazat vytvaˇ nelze z´ıskat adresu konstruktoru ´ Poznamka: Implicitn´ı konstruktor je kaˇzd´y konstruktor, kter´y lze zavolat bez parametru. ˚ Muˇ ˚ ze b´yt pouze jeden pro jednu tˇr´ıdu.
´ r C++ ICP — Seminaˇ
68/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: konstruktory class X { int i; public: X(): i(0) {} X(int); X(const X&); }; X X X X X X
// implicitn´ ı konstruktor (def) // konstruktor s parametrem int // kop´ ırovac´ ı konstruktor
o; // vol´ a o2(55); o2 = 55; o3(o2); *px = new X; *px2 = new X(666);
´ r C++ ICP — Seminaˇ
se // // // // //
X::X() X::X(int) X::X(int) a X::X(const X&) X::X(const X&) X::X() X::X(int) 69/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ren´ı metod pˇrekladaˇcem Implicitn´ı vytvaˇ ´ explicitne, ˇ pˇrekladaˇc vytvoˇr´ı: Pokud nen´ı definovan implicitn´ı konstruktor X::X() kop´ırovac´ı konstruktor X::X(const X&) ´ operator pˇriˇrazen´ı X::operator = (const X&) destruktor X::~X() Pˇrekladaˇcem vytvoˇrene´ metody jsou vˇzdy public a chovaj´ı podobneˇ jako odpov´ıdaj´ıc´ı operace se strukturami v jazyku C. ˇ To nekdy (typicky u tˇr´ıd obsahuj´ıc´ıch ukazatel) nevyhovuje a ´ mus´ıme operace definovat explicitneˇ (nejlepe vˇsechny). ´ Poznamky: Pokud ma´ tˇr´ıda sloˇzky, ktere´ se mus´ı inicializovat (reference), nebo nejsou dostupne´ potˇrebne´ operace, je program chybneˇ vytvoˇren. ´ Implicitn´ı konstruktor nen´ı vytvoˇren, pokud je definovan jak´ykoli jin´y (ne-kop´ırovac´ı) konstruktor. ´ r C++ ICP — Seminaˇ
70/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Kop´ırovac´ı konstruktor ”Copy constructor” ma´ jeden parametr typu const X& (nebo X&) ´ pˇri vzniku objektu kop´ırovan´ ´ ım: je volan deklarace s inicializac´ı jin´ym objektem ´ an´ ´ ı parametru hodnotou pˇredav vracen´ı hodnoty z funkce ´ ı a zpracovan´ ´ ı v´yjimek vyvolan´
pokud je vytvoˇren pˇrekladaˇcem, kop´ıruje objekty po ´ (jejich kop´ırovac´ım konstruktorem) sloˇzkach X::X(const X & o): s1(o.s1), s2(o.s2) {} ´ Poznamky: ˇ ´ nezameˇ novat s operatorem pˇriˇrazen´ı! moˇznost optimalizace ´ r C++ ICP — Seminaˇ
71/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Kop´ırovac´ı konstruktor — pˇr´ıklad
´ Ukazka jake´ konstruktory se pouˇzij´ı v ruzn´ ˚ ych situac´ıch: X f(X p) { X a; X b(a); X c = a; return a; f(a); throw a; }
´ r C++ ICP — Seminaˇ
// // // // // // //
- pˇ red´ an´ ı parametru hodnotou implicitn´ ı konstruktor kop´ ırovac´ ı konstruktor kop´ ırovac´ ı konstruktor kop´ ırovac´ ı konstruktor - kop´ ırovac´ ı konstruktor kop´ ırovac´ ı konstruktor
72/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Inicializace vnoˇren´ych objektu˚ konstruktory vnoˇren´ych objektu˚ se volaj´ı automaticky pˇred ˇ konstruktoru tˇr´ıdy proveden´ım tela ´ ı je dano ´ poˇrad´ı volan´ jejich poˇrad´ım v definici tˇr´ıdy pˇr´ıpadne´ parametry lze pˇredat explicitneˇ — viz pˇr´ıklad: class X { complex c1; complex c2; public: X() {} // implicitn´ ı konstruktory c1 a c2 X(double a) : c2(a), c1(5) {} // poˇ rad´ ı c1 c2 }; ´ ı konstruktoru˚ c1 a c2 ! ´ Poznamka: Pozor na poˇrad´ı volan´ Automaticky vytvoˇren´y konstruktor inicializuje vnoˇrene´ objekty implicitn´ımi konstruktory. ´ r C++ ICP — Seminaˇ
73/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Inicializace pole objektu˚
´ v rostouc´ım poˇrad´ı Konstruktory pro elementy pole jsou volany indexu˚ Pˇr´ıklad: X pole[10]; X *ptr = new X[10]; X p[10] = { X(1), X(2), };
// X::X() // X::X() // X::X(const X&)
´ Poznamka: Moˇzne´ optimalizace kop´ırovac´ıch konstruktoru˚
´ r C++ ICP — Seminaˇ
74/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Inicializace doˇcasn´ych objektu˚
´ ret doˇcasne´ objekty: Pˇrekladaˇc muˇ ˚ ze vytvaˇ implicitneˇ (ve v´yrazech, inicializaci referenc´ı, ...) ´ explicitneˇ zapisem: X(22); // pouˇ zije se X::X(int) ^^^^ funguje jako konverze z int na X ´ Poznamka: Doˇcasne´ objekty pˇrekladaˇc automaticky ruˇs´ı — viz destruktory
´ r C++ ICP — Seminaˇ
75/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Destruktory ´ ´ jmeno je sloˇzeno ze znaku ~ (tilda) a jmena tˇr´ıdy ´ kdyˇz konˇc´ı rozsah platnosti objektu je automaticky vyvolan ´ (konec bloku, ruˇsen´ı nadˇrazeneho objektu, konec programu, ...) nesm´ı m´ıt parametry a nesm´ı vracet hodnotu (je vˇzdy pouze jeden pro jednu tˇr´ıdu) ´ ı (nekdy ˇ ´ ı) muˇ mus´ı b´yt virtualn´ ˚ ze b´yt virtualn´ ´ pˇrekladaˇcem muˇ ˚ ze b´yt implicitneˇ generovan X::~X() {} // destruktor pro tˇ r´ ıdu X ´ v pˇresneˇ destruktory vnoˇren´ych objektu˚ jsou volany ´ ´ poˇrad´ı neˇz jim odpov´ıdaj´ıc´ı konstruktory obracen em u pol´ı se volaj´ı v klesaj´ıc´ım poˇrad´ı indexu˚ ´ r C++ ICP — Seminaˇ
76/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı Destruktory — pokraˇcovan´
´ Poznamky: konˇc´ı-li rozsah platnosti ukazatele na objekt, objekt se ´ neruˇs´ı (zruˇsen´ı provede pouze operator delete) ´ ıch pˇr´ıpadech volat explicitneˇ destruktor lze ve specialn´ ´ ´ pouˇzit´ım plneˇ kvalifikovaneho jmena: X *p; p->X::~X(); // destrukce bez uvolnˇ en´ ı pamˇ eti ´ ı destruktory polymorfn´ıch tˇr´ıd maj´ı b´yt virtualn´
´ r C++ ICP — Seminaˇ
77/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Ruˇsen´ı doˇcasn´ych objektu˚
´ ´ Doˇcasne´ objekty jsou automaticky ruˇseny vˇzdy v obracen em poˇrad´ı jejich vzniku: ´ vznikly na konci v´yrazu ve kterem jde-li o inicializaci, potom aˇz po dokonˇcen´ı inicializace odkazuje-li se na neˇ reference, pak ´ vznikly nebo pˇri zaniku ´ na konci bloku ve kterem reference (co nastane dˇr´ıve) na konci konstruktoru v jehoˇz inicializaˇcn´ı sekci vznikly na konci funkce v pˇr´ıpadeˇ jejich vzniku v pˇr´ıkazu return
´ r C++ ICP — Seminaˇ
78/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Konverze
ˇ typu v´yrazu na jin´y typ (T1 → T2) Pouˇz´ıvaj´ı se pro zmenu Kategorie konverzn´ıch operac´ı standardn´ı konverze (definovane´ jazykem) uˇzivatelske´ konverze (definovane´ v programu): ´ jen kdyˇz jsou jednoznaˇcne´ a pˇr´ıstupne. ´ Jsou aplikovany ´ ı jeˇsteˇ pˇred kontrolou Ke kontrole jednoznaˇcnosti dochaz´ ´ pˇr´ıstupov´ych prav. ´ Implicitneˇ muˇ pouze jedna uˇzivatelska´ ˚ ze b´yt aplikovana konverze (tj. neprovede se konverze A → B → C, kdyˇz neexistuje pˇr´ımo A → C)
´ r C++ ICP — Seminaˇ
79/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı Konverze — pokraˇcovan´
Uˇzivatelske´ konverze lze specifikovat pomoc´ı: konverzn´ıch konstruktoru˚ (typ → tˇr´ıda) konstruktory, ktere´ lze volat s jedn´ım argumentem ´ ı implicitn´ımu pouˇzit´ı specifikace explicit zabran´
´ u˚ (tˇr´ıda → typ) konverzn´ıch operator metody pojmenovane´ operator T ´ nemaj´ı navratov´ y typ a jsou bez parametru˚ ´ ˇ ı a mohou b´yt virtualn´ ´ ı tyto operatory se ded´
´ r C++ ICP — Seminaˇ
80/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Konverze — pˇr´ıklady struct T { T(int); // int --> T T(const char*, int =0); // const char* --> T explicit T(U); // explicitn´ ı U --> T operator int(); // T --> int }; void f(T p, U u) { T b = "text"; // b = T("text",0) T c(u); // OK: explicitn´ ı konverze // T d = u; // chyba: implicitn´ ı konverze b = 5; // b = T(5) b = T(u); // OK: U --> T int i = c; // T --> int implicitn´ ı konverze i = int(c); // T --> int i = static_cast(c); // T --> int if(i<1) f(66,u); // int --> T } ´ r C++ ICP — Seminaˇ
81/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı operator ´ u˚ Pˇreteˇ ˇ zovan´ ´ ı = pˇrisouzen´ı v´ıce v´yznamu˚ jednomu symbolu Pˇreteˇ ´ ı podle kontextu rozliˇsen´ı operac´ı se provad´ ˇ zovat vˇsechny operatory ´ lze pˇreteˇ C++ kromeˇ ´ nasleduj´ ıc´ıch: . .* :: ?: a preprocesorov´ych # ## ˇ poˇcet operandu˚ operator ´ u˚ ani jejich prioritu nelze zmenit a pravidla pro asociativitu alesponˇ jeden parametr mus´ı b´yt tˇr´ıda nebo v´ycˇ et je vhodne´ dodrˇzovat jista´ pravidla: ´ ´ u˚ zachovavat smysl operator ˇ a´ operace (napˇr´ıklad int + int) nemen´ ˇ ı pokud vestaven ´ y operand, nemaj´ı to delat ˇ ani pˇret´ızˇ ene´ varianty zˇ adn´
ˇ ı zapisu ´ zpˇrehlednen´ programu˚ ´ r C++ ICP — Seminaˇ
82/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı operator ´ u˚ 2 Pˇreteˇ
ˇ ´ ´ implicitne: ˇ Nekter e´ operatory jsou definovany pˇriˇrazen´ı (operator =) ´ ı adresy objektu (unarn´ ´ ı &) z´ıskan´ ˇ cˇ lenu struktury (.) v´yber
´ r C++ ICP — Seminaˇ
83/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı operator ´ u˚ 3 Pˇreteˇ ´ ´ metody, Operatory je moˇzne´ definovat jako (nestaticke) ´ nebo jako funkce (znak @ reprezentuje libovoln´y operator): v´yraz @a a@b a=b a[b] a-> a@
jako metoda (a).operator@ () (a).operator@ (b) (a).operator= (b) (a).operator[](b) (a).operator->() (a).operator@ (0)
jako funkce operator@ (a) operator@ (a, b)
operator@ (a, 0)
´ ´ ´ ı Pˇrekladaˇc vˇzdy pˇrevede zapis operatoru na volan´ ´ odpov´ıdaj´ıc´ı operatorov e´ funkce nebo metody. ´ obeˇ varianty, je aplikovano ´ Jsou-li deklarovany standardn´ı ´ ˇ testovan´ı argumentu˚ pro reˇsen´ı nejednoznaˇcnosti. ´ r C++ ICP — Seminaˇ
84/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı unarn´ ´ ıch operator ´ u˚ Pˇreteˇ ´ ıch operator ´ u˚ Moˇzne´ formy deklarace unarn´ nestaticka´ metoda bez parametru˚ funkce (ne metoda) s jedn´ım parametrem ´ ı operator, ´ Kdyˇz znak @ reprezentuje unarn´ potom: @x a x@ ´ ´ ı metody: muˇ budˇ jako volan´ ˚ ze b´yt oboj´ı interpretovano x.operator @() ´ ı funkce: nebo jako volan´ operator @(x) ´ podle formy deklarace operatoru. ´ r C++ ICP — Seminaˇ
85/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı unarn´ ´ ıch operator ´ u˚ 2 Pˇreteˇ ´ Prefixove´ a postfixove´ operatory ++ -- lze rozliˇsit pomoc´ı ´ ´ dodateˇcneho fiktivn´ıho parametru operatoru: class Y { // ... public: Y operator ++() { /* inkrementace ++x */ } Y operator ++(int) { /* inkrementace x++ */ } }; Y x,y; y = ++x; y = x++;
´ r C++ ICP — Seminaˇ
// vol´ a // vol´ a
Y::operator ++() Y::operator ++(int)
86/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı binarn´ ´ ıch operator ´ u˚ Pˇreteˇ ´ ıch operator ´ u˚ Moˇzne´ formy deklarace binarn´ nestaticka´ metoda s jedn´ım parametrem ˇ funkce (ne metoda) se dvema parametry V´yraz: x@y ´ budˇ jako volan´ ´ ı metody: je interpretovan x.operator @(y) ´ ı funkce: nebo jako volan´ operator @(x,y) ´ r C++ ICP — Seminaˇ
87/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı binarn´ ´ ıch operator ´ u˚ — pˇr´ıklad Pˇreteˇ class Complex { double re, im; public: Complex(): re(0), im(0) {} Complex(double r, double i=0): re(r), im(i) {} friend Complex operator +(Complex c1, Complex c2); // friend funkce ˇ reˇ s´ ı probl´ em: 1 + Complex(1,2) }; Complex operator +(Complex c1, Complex c2) { return Complex(c1.re + c2.re, c1.im + c2.im); } Complex a(0,1), b(1,0), c; c = a + b; // pˇ ret´ ıˇ zen´ y oper´ ator + c = operator+(a,b); // oper´ atorov´ a funkce ´ r C++ ICP — Seminaˇ
88/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı operatoru ´ Pˇreteˇ pˇriˇrazen´ı T& T::operator= (const T&); ´ kop´ırovac´ı operator =, pˇrekladaˇc jej nen´ı-li definovan ´ vytvoˇr´ı jako pˇriˇrazen´ı po jednotliv´ych sloˇzkach ˇ ı se (na rozd´ıl od ostatn´ıch operatorov´ ´ neded´ ych funkc´ı) ´ ı muˇ ˚ ze b´yt virtualn´ ´ Poznamky: pˇri implementaci je tˇreba uvaˇzovat i moˇznost pˇriˇrazen´ı typu a = a ´ pˇriˇrazovan´ ´ ı objektu˚ specifikac´ı private muˇ ˚ zeme zabranit ˇ operatoru, ´ (Jestliˇze nedefinujeme ani telo bude i pˇri jeho ´ pouˇzit´ı uvnitˇr tˇr´ıdy hlaˇ ´ sena chyba pˇri pˇr´ıpadnem ´ ı programu.) sestavovan´ ´ r C++ ICP — Seminaˇ
89/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı operatoru ´ Pˇreteˇ pˇriˇrazen´ı — pˇr´ıklad class String { // ... odkaz na data public: // copy-assignment: String & operator = (const String & str) { if(&str!=this) // ... pˇ riˇ razen´ ı dat return *this; } String & operator = (const char *cstr) { // ... pˇ riˇ razen´ ı dat return *this; } // ... dalˇ s´ ı metody atd. }; ´ r C++ ICP — Seminaˇ
90/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı operatoru ´ ´ ı funkce Pˇreteˇ volan´
typ T::operator() (parametry); operator()mus´ı b´yt nestaticka´ metoda muˇ ˚ ze m´ıt libovoln´y poˇcet parametru˚ ´ ı x(a1,a2), kde x je objekt je Napˇr´ıklad volan´ ´ interpretovano jako x.operator()(a1,a2). Pouˇzit´ı: funkˇcn´ı objekty v STL
´ r C++ ICP — Seminaˇ
91/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı operatoru ´ ´ ı pole Pˇreteˇ indexovan´
typ_prvku& T::operator[] (typ_indexu); ´ pouze jako nestaticka´ metoda muˇ ˚ ze b´yt definovan ´ ı operator ´ ´ ı a[b] Binarn´ indexovan´ ´ jako a.operator[](b) je interpretovan ´ ´ ı: v´ıcenasobn e´ indexovan´ ´ ´ ı pomocna´ tˇr´ıda (v´ıce tˇr´ıd) s operatorem indexovan´ ´ ´ ı zakladn´ ´ operator indexovan´ ı tˇr´ıdy vrac´ı referenci na objekt pomocne´ tˇr´ıdy ˇ indexovateln´y pomocn´y objekt je opet ˇ eho ´ v´ysledkem mus´ı b´yt reference na prvek v´ıcerozmern pole
´ r C++ ICP — Seminaˇ
92/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı pˇr´ıstupoveho ´ ´ Pˇreteˇ operatoru ->
typ T::operator-> (); ´ za unarn´ ´ ı operator ´ operator-> je povaˇzovan a mus´ı b´yt ´ jako nestaticka´ metoda. definovan ´ jako (x.operator->())->m V´yraz x->m, je interpretovan ˇ operator->() mus´ı vracet bud: ukazatel na objekt tˇr´ıdy nebo ´ objekt jine´ tˇr´ıdy pro kterou je operator-> definovan
´ r C++ ICP — Seminaˇ
93/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Omezen´ı pro doˇcasne´ objekty ˇ e´ (vytvoˇrene´ C++ nedovol´ı volat metody pro doˇcasne´ promenn napˇr´ıklad implicitn´ı konverz´ı). Pˇr´ıklad: class X { int i; public: X(int _i=0) : i(_i) {} X operator + (const X &b) const { return X(i + b.i); } }; X a, b; a = 5 + b; ´ r C++ ICP — Seminaˇ
// nelze v C++98 94/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı funkc´ı Pˇreteˇ
´ Moˇznost deklarovat v´ıce funkc´ı se stejn´ym jmenem ´ ı rozliˇsuj´ı se podle poˇctu a typu argumentu˚ pˇri volan´ souvislost s typovou kontrolou ´ ı funkc´ı pravidla pro vyhledan´ ´ nejednoznaˇcnosti (”ambiguity”) problem ´ ´ funkce nelze rozliˇsit jen podle navratov eho typu ´ se berou v uvahu pˇr´ıstupova´ prava aˇz po kontrole ´ jednoznaˇcnosti ´ Poznamka: typedef nedefinuje samostatn´y typ
´ r C++ ICP — Seminaˇ
95/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ zovan´ ´ ı funkc´ı – pˇr´ıklad Pˇreteˇ
void print(double); void print(long); void F() { print(1L); print(1.0); print(1); }
// tiskne long // tiskne double // CHYBA: nejednoznaˇ cnost
ˇ sen´ı nejednoznaˇcnosti: Reˇ ´ ı nebo definice dalˇs´ı funkce void print(int); pˇretypovan´
´ r C++ ICP — Seminaˇ
96/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Rozliˇsen´ı typu˚
ˇ zovan´ ´ ı nelze rozliˇsit nekter ˇ ´ Poznamka: Pˇri pˇreteˇ e´ typy: void f(int); void f(const int);
// CHYBA - nelze rozliˇ sit
void g(int*); void g(const int*); // ukazatele lze rozliˇ sit void h(int&); void h(const int&); // reference lze rozliˇ sit
´ r C++ ICP — Seminaˇ
97/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ an´ ´ ı prostoru˚ jmen Pravidla pro prohledav (”Argument Dependent Lookup” = ADL = ”Koenig lookup”) ´ ı funkce f s pˇr´ıpadn´ymi parametry se hleda´ Pˇri volan´ ´ ych funkc´ı takto: odpov´ıdaj´ıc´ı mnoˇzina kandidatsk´ 1 ´ an´ ´ ı funkce v prostoru jmen se pouˇzije pouze pro vyhledav ´ jmeno funkce 2 ´ ıho smerem ˇ v hierarchii prostoru˚ jmen hleda´ se od aktualn´ ´ ımu (tˇr´ıda je prostorem jmen); nekdy ˇ ke globaln´ se uvaˇzuj´ı i dalˇs´ı souvisej´ıc´ı prostory podle typu argumentu˚ (ADL). 3 ´ ´ ´ ı se najde-li se funkce/metoda stejneho jmena, provad´ rozliˇsen´ı funkce podle typu a poˇctu parametru˚ (”viable ´ functions” – viz dale) 4
´ ı se chyba nenajde-li se odpov´ıdaj´ıc´ı funkce hlas´
´ r C++ ICP — Seminaˇ
98/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ odpov´ıdaj´ıc´ı funkce Pravidla pro v´yber ´ u˚ se vyberou ”viable” funkce podle: Z mnoˇziny kandidat poˇctu argumentu˚ (vˇcetneˇ ...) moˇzn´ych implicitn´ıch konverz´ı argumentu˚ ˇ ´ vyhovuj´ıc´ı funkce: Z techto funkc´ı se vybere nejlepe 1
2
3
4 5
Shoda typu˚ (bez konverz´ı – kromeˇ nevyhnuteln´ych: ´ pole → ukazatel, jmeno funkce → ukazatel na funkci, T → const T) Shoda typu˚ po konverzi na int (char → int, short → int, atd.) a float → double Shoda po proveden´ı standardn´ıch konverz´ı (int → double, odvozen´ a-tˇ r´ ıda * → b´ azov´ a-tˇ r´ ıda *) Shoda po proveden´ı uˇzivatelem definovan´ych konverz´ı ´ Pouˇzit´ı nespecifikovaneho poˇctu argumentu˚ (...)
Nalezen´ı dvou a v´ıce stejneˇ dobr´ych funkc´ı vede k chybeˇ – jde o nejednoznaˇcnost (”ambiguity”). ´ r C++ ICP — Seminaˇ
99/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
void f(int); // glob´ aln´ ı funkce class T { public: T(int); // konverze int ---> T operator int(); // konverze T ---> int void f(long); // --- kandid´ at 1 void f(double); // --- kandid´ at 2 void m() { f(5); // chyba --- nejednoznaˇ cnost ::f(5); // O.K. --- glob´ aln´ ı funkce } friend int operator + (T x, T y); }; T x, y; x = 5 + y; // nejednoznaˇ cnost: 5+int(y) nebo T(5)+y ? ´ Moˇzne´ ˇreˇsen´ı: zakaz jedne´ z konverz´ı, pˇr´ıpadneˇ specifikace explicit u konstruktoru ´ r C++ ICP — Seminaˇ
100/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Vstup/v´ystupn´ı operace s vyuˇzit´ım streamu˚ ˇ ı pojmu soubor stream (proud) – objekt, zobecnen´ #include #include tˇr´ıdy ios, istream, ostream, iostream, ifstream, ofstream, fstream a dalˇs´ı standardn´ı streamy: cin, cout, cerr ´ u˚ << a >> pro vstup/v´ystupn´ı operace (jsou pouˇzit´ı operator ´ pro vˇsechny vestaven ˇ e´ typy) definovany ˇ ´ moˇznost doplnovat operatory << a >> pro uˇzivatelem ´ definovane´ typy (bez zasahu do implementace streamu) ˚ ´ u! pozor na priority operator ˚
´ r C++ ICP — Seminaˇ
101/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Definice a pouˇzit´ı vstup/v´ystupn´ıch operac´ı
´ Zapis cerr << "x=" << x << ’\n’; ´ je ekvivalentn´ı zapisu operator<<(operator<<(operator<<(cerr,"x="),x),’\n’); ´ pro typ objektu x a tiskne x zpusobem, kter´y je definovan ˚ int x = 123; Complex x(1,2.4)
´ r C++ ICP — Seminaˇ
tiskne: tiskne:
x=123 x=(1,2.4)
102/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Pˇr´ıkld definice v´ystupn´ıho operatoru
Pˇr´ıklad pro jednoduchou tˇr´ıdu Complex // v´ ystupn´ ı form´ at: (f,f) ostream& operator<< (ostream& s, Complex z) { return s <<’(’<< real(z) <<’,’<< imag(z) <<’)’; }
´ Poznamka: Moˇznost tisku cˇ ´ısla f m´ısto (f,0)
´ r C++ ICP — Seminaˇ
103/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Pˇr´ıkld definice vstupn´ıho operatoru // vstupn´ ı form´ aty:
f
(f)
(f,f)
istream& operator>>(istream& s, Complex& a) { double re = 0, im = 0; char c = 0; s >> c; // ˇ cte prvn´ ı nemezerov´ y znak if( c == ’(’ ) { s >> re >> c; if( c == ’,’ ) s >> im >> c; if( c != ’)’ ) s.setstate(ios::failbit); // chybov´ y stav } else { ´ ı) (pokraˇcovan´ ´ r C++ ICP — Seminaˇ
104/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ´ ı Pˇr´ıkld definice vstupn´ıho operatoru — pokraˇcovan´ else { s.putback(c); s >> re; } if( s ) a = Complex(re,im); return s; } ˇ s´ı, protoˇze je nutne´ oˇsetˇrit ´ Poznamka: Vstup je sloˇzitejˇ vˇsechny varianty ´ z jako if(s.fail()) a podm´ınka ´ Poznamka: if(s) je toteˇ plat´ı, kdyˇz je nastaven pˇr´ıznak ios::failbit (chybne´ ´ an´ ´ ı vstupu, pokus o cˇ ten´ı za EOF) nebo ios::badbit formatov ´ zneji ˇ poruˇsen). (stream je vaˇ ´ r C++ ICP — Seminaˇ
105/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Manipulatory
flush ws hex endl Pˇr´ıklad:
´ ´ vyprazdn´ ı vyrovnavac´ ı pameˇ ˇt ˇ pˇreskoˇc´ı mezery (oddelovaˇ ce) ´ pouˇzije sˇ estnactkovou notaci ´ nov´y ˇradek ´ u˚ pouˇzit´ı manipulator
cout << x << flush << y << flush; cin >> ws >> x; cout << 1234 << hex << 1234 << endl;
´ r C++ ICP — Seminaˇ
106/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Manipulatory s parametry
setfill(char) setprecision(int) setw(int) Pˇr´ıklad:
ˇ y znak v´yplnov´ pˇresnost sˇ ´ıˇrka tisku
´ u˚ pouˇzit´ı manipulator
cout <<setw(4)<<setfill(’#’)<< 33 << "+" << 22; v´ ystup: ##33+22 ´ ´ Poznamka: Nastaven´ı manipulatoru setw() plat´ı pouze pro ´ jednu tisknutou poloˇzku, ostatn´ı manipulatory plat´ı aˇz do dalˇs´ı ˇ zmeny ´ r C++ ICP — Seminaˇ
107/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ se soubory Prace ´ s diskov´ymi soubory jsou definovany ´ tˇr´ıdy Pro praci fstream ifstream ofstream ´ an´ ´ ı streamu na soubor lze provest ´ pˇri vzniku objektu Navaz ´ ım metody open. nebo volan´ Metodou clear() je moˇzne´ zruˇsit chybov´y stav streamu. ´ Poznamka: Kombinace streamu˚ a C-funkc´ı (printf,...) muˇ ˚ ze ´ k problem ´ um vest ˚ v poˇrad´ı v´ystupu. ˚
´ r C++ ICP — Seminaˇ
108/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ se soubory — pˇr´ıklad Prace #include using namespace std; ifstream from("soubor1.txt"); ofstream to("soubor2.txt"); fstream f("soubor3.txt", ios::in | ios::out); void copy(ifstream &from, ofstream &to) { char ch; // m˚ uˇ ze b´ yt char (EOF se testuje jinak) while(from.get(ch)) // kopie souboru (pomal´ e!) to.put(ch); if(!from.eof() || to.bad()) // test chyb error("chyba!"); } ´ r C++ ICP — Seminaˇ
109/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ cnost Dediˇ kl´ıcˇ ov´y koncept OOP ´ ı nov´ych tˇr´ıd z jiˇz existuj´ıc´ıch odvozovan´ ´ bazov e´ (”Base”) a odvozene´ (”Derived”) tˇr´ıdy class D : public B { // tˇ r´ ıda D dˇ ed´ ı tˇ rı ´du B // nov´ e poloˇ zky, nov´ e a modifikovan´ e metody }; ´ ˇ cnost jednoducha´ a nasobn a´ dediˇ ´ sd´ılen´ı kodu — znovupouˇzitelnost (reusability) sd´ılen´ı rozhran´ı — polymorfismus ˇ ı vˇsechny datove´ sloˇzky bazov ´ ˇ zne´ tˇr´ıda ded´ e´ tˇr´ıdy a beˇ metody (ne konstruktory, destruktor, operator=) ˇ en´ ˇ ych cˇ lenu˚ tˇr´ıdy lze pouˇz´ıvat pouze ty co byly ze zded public nebo protected ´ r C++ ICP — Seminaˇ
110/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ en´ ˇ ı private, public, protected Ded ´ u zded ˇ en´ ˇ ych prvku: Je moˇzne´ specifikovat pˇr´ıstupova´ prava ˚ class D : public B1, protected B2, B3 {}; implicitn´ı je private u class D, a public u struct D ˇ ı atributy pˇr´ıstupu takto: odvozena´ tˇr´ıda ded´ ˇ ´ zded ˇ en´ ˇ ych zmena pˇr´ıstupov´ych prav ˇ en´ ˇ ı cˇ lenu˚ z B v odvozene´ tˇr´ıdeˇ D zpusob ded ˚ ˇ eno ˇ public B public i protected nezmen protected B public a protected bude protected private B vˇsechny cˇ leny budou private ˇ pˇr´ıstupova´ prava ´ u jednotliv´ych zded ˇ en´ ˇ ych poloˇzek Lze zmenit pouˇzit´ı using deklarace (viz. prostory jmen) ˇ ded ˇ en´ ˇ ım lze obnovit max. na puvodn´ ı, kdyˇz byly zpˇr´ısneny ˚ ´ r C++ ICP — Seminaˇ
111/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı konstruktoru˚ a dediˇ ˇ cnost Poˇrad´ı volan´ Konstruktor odvozene´ tˇr´ıdy je sloˇzen z: ´ ı konstruktoru bazov ´ volan´ e´ tˇr´ıdy, ´ ı pˇr´ıpadn´ych konstruktoru˚ lokaln´ ´ ıch objektu˚ volan´ ˇ a (v poˇrad´ı jak jsou uvedeny ve tˇr´ıde) ´ ı telo ˇ konstruktoru. nakonec se provad´ ´ ı parametru˚ konstruktorum Pˇredan´ ˚ je moˇzne´ za dvojteˇckou ´ u˚ konstruktoru (viz nasleduj´ ´ v seznamu inicializator ıc´ı pˇr´ıklad). ´ v pˇresneˇ ´ Poznamka: Destruktory jsou vˇzdy volany ´ ´ poˇrad´ı neˇz jim odpov´ıdaj´ıc´ı konstruktory. obracen em
´ r C++ ICP — Seminaˇ
112/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı konstruktoru˚ — pˇr´ıklad Poˇrad´ı volan´ V pˇr´ıkladu je hruba´ chyba: class Base { int x; public: Base (int i): x(i) {} }; class Derived : Base { int a; public: Derived(int i) : a(i*10), Base(a) {} // chyba! // do Base je pˇ red´ ana neinicializovan´ a hodnota a ! // konstruktor provede: // 1) Base::Base(a) neinicializovan´ a hodnota a // 2) a(i*10) inicializace ˇ clenu a (pozdˇ e) }; ´ r C++ ICP — Seminaˇ
113/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı konstruktoru˚ — pˇr´ıklad 2 Poˇrad´ı volan´ struct base { //.... base(int i=0) { } }; class derived : base { complex x; // vnoˇ ren´ e objekty complex y; int z; public: derived() : x(2,1) { f(); } // konstruktor provede: // 1) base::base() // 2) complex::complex(2,1) pro x // 3) complex::complex() pro y // z nen´ ı inicializov´ ano = nekorektn´ ı k´ od // 4) vol´ an´ ı f() }; ´ r C++ ICP — Seminaˇ
114/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı metody Virtualn´ ˇ ı Metody oznaˇcene´ kl´ıcˇ ov´ym slovem virtual umoˇznuj´ polymorfismus: ´ v bazov e´ tˇr´ıdeˇ definuj´ı rozhran´ı spoleˇcne´ vˇsem odvozen´ym ´ tˇr´ıdam ´ je definovana ´ v odvozen´ych tˇr´ıdach odpov´ıdaj´ıc´ı implementace metod ´ ´ pˇresneˇ pˇri pouˇzit´ı spoleˇcneho rozhran´ı nen´ı tˇreba znat ˇ tˇr´ıdu objektu (jeˇsteˇ nemus´ı existovat) a pˇresto je pˇri behu ˇ ´ ı odpov´ıdaj´ıc´ıch metod – tzv. programu zajiˇsteno volan´ pozdn´ı vazba (”late binding”). ´ ı ma´ typicky tvar: Polymorfn´ı volan´ ukazatel->vmetoda()
´ r C++ ICP — Seminaˇ
115/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı metody 2 Virtualn´ ´ ı destruktory, ktere´ umoˇznuj´ ˇ ı korektneˇ Lze definovat virtualn´ ruˇsit prvky datov´ych struktur ˇ m´ıt virtualn´ ´ ı ´ Poznamka: Polymorfn´ı tˇr´ıdy by vˇzdy mely destruktor. ´ ı metody se mohou liˇsit ve vracenem ´ typu jestliˇze Virtualn´ ˇ ı nasleduj´ ´ splnuj´ ıc´ı podm´ınky: ´ ı metoda vrac´ı ukazatel nebo pˇredefinovana´ virtualn´ ´ referenci na bazovou tˇr´ıdu pˇrepisuj´ıc´ı funkce vrac´ı ukazatel nebo referenci na odvozenou tˇr´ıdu (tzv. kovariantn´ı typ)
´ r C++ ICP — Seminaˇ
116/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı metody — pˇr´ıklad Virtualn´ class B { public: virtual B* vf1() { void f() { }; class C : public B { public: C* vf1() { cout << void f() { cout << }; class D : public B { public: virtual D* vf1() { void f() { }; ´ r C++ ICP — Seminaˇ
cout << "B"; return this; } cout << "B"; }
"C"; return this; } // virtual "C"; }
cout << "D"; return this; } cout << "D"; }
117/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı metody — pˇr´ıklad — pokraˇcovan´ ´ ı Virtualn´ int main() { B b; C c; D d; b.f(); // "B" - obyˇ cejn´ a metoda c.f(); // "C" d.f(); // "D" b.vf1(); // "B" - stejn´ e c.vf1(); // "C" d.vf1(); // "D" B *bp = &c;// bp->vf1(); // bp->f(); // bp = &d; // bp->vf1(); // bp->f(); //
uk. na b´ azovou tˇ r´ ıdu - rozhran´ ı "C"-podle skuteˇ cn´ e tˇ r´ ıdy objektu c "B"-podle typu ukazatele bp ukazuje na objekt tˇ r´ ıdy D "D"-podle skuteˇ cn´ e tˇ r´ ıdy objektu d "B"-podle typu ukazatele bp
} ´ r C++ ICP — Seminaˇ
118/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı metody — implementace Virtualn´ ´ ıch metod je vhodne´ ved ˇ et, ˇ jak je Pro pochopen´ı virtualn´ ´ uveden´y mechanismus obvykle implementovan: ´ ımi metodami ma´ tzv. tabulku Kaˇzda´ tˇr´ıda s virtualn´ ´ ıch metod (VMT - Virtual Method Table), ve ktere´ virtualn´ ´ ı metody tˇr´ıdy. jsou odkazy na vˇsechny virtualn´ ˇ en´ ˇ ı (pˇri pˇrekladu) se pˇrevezme obsah VMT bazov ´ Pˇri ded e´ ´ ı metody, ktere´ byly pˇredefinovany ´ tˇr´ıdy, odkazy na virtualn´ se nahrad´ı nov´ymi a na konec VMT se dopln´ı odkazy na ´ ı metody. pˇr´ıpadne´ nove´ virtualn´ ´ ımi metodami obsahuje odkaz Kaˇzd´y objekt tˇr´ıdy s virtualn´ ´ ıch metod na tabulku virtualn´ ´ ı pouˇzije ukazatel v objektu, vybere Polymorfn´ı volan´ odpov´ıdaj´ıc´ı poloˇzku z VMT a zavola´ metodu. ´ r C++ ICP — Seminaˇ
119/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad implementace polymorfismu class B { public: virtual void vf1(); // rozhran´ ı // ... } b; class C : public B { // mus´ ı b´ yt public public: virtual void vf1(); // ... } c; B *bp = &c;
´ r C++ ICP — Seminaˇ
// polymorfn´ ı rozhran´ ı: bp->vf1()
120/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Pˇr´ıklad implementace polymorfismu — obrazek
VMT B b vf1B
void vf1() {} VMT C c vf1C
void vf1() {}
bp ´ r C++ ICP — Seminaˇ
121/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ r k polymorfismu Komentaˇ ´ ´ ı metodu, je volana ´ Volame-li virtualn´ nepˇr´ımo pˇres VMT – to ˇ umoˇznuje volat odpov´ıdaj´ıc´ı metodu i kdyˇz tˇr´ıda objektu nen´ı ´ ´ ´ pˇrekladaˇci znama (mame pouze ukazatel na objekt bazov e´ tˇr´ıdy). Informace o tˇr´ıdeˇ objektu je vlastneˇ ukryta v odkazu na ´ tˇr´ıdy, kter´y je souˇcast´ ´ ı kaˇzdeho ´ VMT teto objektu. ´ ´ ˇ Mame-li ukazatel na objekt bazov e´ tˇr´ıdy B, muˇ ˚ zeme do nej pˇriˇradit ukazatel na tˇr´ıdu z n´ı odvozenou. Pomoc´ı tohoto ukazatele muˇ ˚ zeme potom volat metody definovane´ ve tˇr´ıdeˇ B. ´ ı, budou volany ´ metody, ktere´ Pokud jsou tyto metody virtualn´ pˇr´ısluˇs´ı skuteˇcne´ tˇr´ıdeˇ objektu na kter´y se ukazuje. ´ Muˇ tˇr´ıdu tak, aby poskytovala vhodne´ ˚ zeme definovat bazovou rozhran´ı pro celou skupinu odvozen´ych tˇr´ıd (ktere´ mohou b´yt ´ pozdeji) ˇ a pracovat potom s objekty (pˇres toto definovany ´ ˇ rozhran´ı) nezavisle na jejich tˇr´ıde. ´ r C++ ICP — Seminaˇ
122/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ r k polymorfismu — pokraˇcovan´ ´ ı Komentaˇ
´ Pˇr´ıkladem muˇ a´ tˇr´ıda PrvekSeznamu, ktera´ definuje ˚ ze b´yt bazov obecne´ vlastnosti jednoho prvku seznamu, se kter´ym um´ı pracovat tˇr´ıda Seznam. Potom lze ze tˇr´ıdy PrvekSeznamu odvodit ´ jakoukoli novou tˇr´ıdu a jej´ı objekty ukladat do seznamu, i kdyˇz ´ vˇsechny jejich vlastnosti nebyly jeˇsteˇ znamy v dobeˇ psan´ı ´ implementace tˇr´ıdy Seznam (bylo znamo pouze rozhran´ı definovane´ tˇr´ıdou PrvekSeznamu).
´ r C++ ICP — Seminaˇ
123/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı virtualn´ ´ ıch metod tˇr´ıdy v konstruktoru Volan´
´ en´ ˇ ı konstruktoru˚ (a destruktoru) ´ Poznamka: Pˇri provad ˚ se ´ ı virtualn´ ´ ıch metod neuplatnuje ˇ mechanismus volan´ na metody ´ konstruovaneho objektu — konstruktor vˇzdy nastav´ı svoji ´ ıch metod a nelze tedy volat metody tabulku virtualn´ odvozen´ych tˇr´ıd. ´ ´ ı virtualn´ ´ ı metody, Duvodem jsou moˇzne´ problemy pˇri volan´ ˚ ktera´ pracuje s jeˇsteˇ neinicializovan´ymi sloˇzkami objektu. ´ ame ´ ´ ı — viz ´ Poznamka: Pˇredpoklad polymorfn´ı volan´ ´ nasleduj´ ıc´ı pˇr´ıklad.
´ r C++ ICP — Seminaˇ
124/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı virtualn´ ´ ıch metod v konstruktoru — pˇr´ıklad Volan´ struct A { A() { m(this); } void m(A *bp) { bp->V(); } virtual void V() { cout << }; class B : public A { int i; public: B(): i(9) { m(this); } virtual void V() { cout << }; int main() { B b; // vytiskne A *bp = &b; bp->V(); // vytiskne } ´ r C++ ICP — Seminaˇ
’A’ ; }
’B’ << i << ’ ’ ; }
AB9 a nikoli B?B9 B9 125/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ eˇ virtualn´ ´ ı metody Cist ”pure virtual functions” ´ ı metoda nemus´ı b´yt definovana. ´ virtualn´ Potom mus´ı b´yt ´ ˇ ˇ ´ deklarovana jako tzv. ciste virtualn´ı metoda: class B { virtual void pvf(int) = 0; }; ´ se tato metoda ded´ ˇ ı jako ve vˇsech odvozen´ych tˇr´ıdach ´ ı, dokud nen´ı definovana. ´ cˇ isteˇ virtualn´ ´ ı rozhran´ı v bazov´ ´ ´ jsou vhodne´ pro definovan´ ych tˇr´ıdach ´ ıch pˇr´ıpadech lze doplnit definici ´ Poznamka: Ve specialn´
´ r C++ ICP — Seminaˇ
126/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Abstraktn´ı tˇr´ıdy ´ eˇ jednou cˇ isteˇ virtualn´ ´ ı metodou tˇr´ıdy s minimaln ´ ´ ´ ˇ en´ ˇ ı pouˇzitelne pouze jako bazove tˇr´ıdy pˇri ded ´ ret zˇ adn ´ e´ objekty nelze vytvaˇ lze pouˇz´ıt ukazatel/referenci na abstraktn´ı tˇr´ıdu Pˇr´ıklad: class shape { // abstraktn´ ı tˇ r´ ıda - obrazec point center; public: // definice rozhran´ ı virtual void rotate(int) =0; virtual void move(int,int) =0; virtual void draw() =0; //... }; ...(pokraˇ cov´ an´ ı) ´ r C++ ICP — Seminaˇ
127/211
´ Uvod Jazyk Knihovny
class Circle : int radius; public: virtual void virtual void virtual void //... };
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
public shape { // kruˇ znice
rotate(int) {} // definice move(int,int); draw();
shape s; // nelze vytvoˇ rit objekt - chyba Circle c; // tˇ r´ ıda Circle nen´ ı abstraktn´ ı shape *sp=&c; // ukazatel na abstraktn´ ı tˇ r´ ıdu sp->rotate(); // vol´ an´ ı pˇ res polymorfn´ ı rozhran´ ı
´ r C++ ICP — Seminaˇ
128/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator typeid
typeid ( v´ yraz ) typeid ( typ ) ´ ´ an´ ´ ı informac´ı o typu objektu za behu ˇ operator pro z´ıskav programu pˇrekladaˇc generuje typove´ informace a ty jsou dostupne´ ˇ pˇri behu aplikace (RTTI = Run-Time Type Information) V´ysledek typeid(v´ yraz) je typu const type_info& type_info reprezentuje popis typu v´yrazu v´ yraz je reference na polymorfn´ı typ nebo *ukazatel (je-li ukazatel==0, pak dojde k v´yjimce bad_typeid)
´ r C++ ICP — Seminaˇ
129/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator typeid — pˇr´ıklad
class X { // polymorfn´ ı tˇ r´ ıda // ... virtual void f(); }; void g(X *p) { const type_info &a = typeid(p); const type_info &b = typeid(*p);
// X* // tˇ rı ´da X // nebo odvozen´ a
}
´ r C++ ICP — Seminaˇ
130/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Tˇr´ıda type info ´ deklarovano v napˇr´ıklad takto: class type_info { public: // rozhran´ ı: virtual ~type_info(); int operator==(const type_info&) const; int operator!=(const type_info&) const; int before(const type_info&) const; const char *name() const; private: // zak´ azan´ e operace: type_info(const type_info&); type_info & operator= (const type_info&); // ... implementaˇ cnˇ e z´ avisl´ a reprezentace }; ´ r C++ ICP — Seminaˇ
131/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı Tˇr´ıda type info — pokraˇcovan´
´ celem before je moˇznost ˇradit objekty type_info. Uˇ ´ zˇ adn´ ´ y vztah mezi dediˇ ˇ cnost´ı a before. Nen´ı definovan ˇ Metoda name vrac´ı ˇretezec jednoznaˇcneˇ reprezentuj´ıc´ı typ. ˇ ´ ´ Poznamka: obsah rˇetezce je implementaˇcneˇ zavisl´ y ´ (nemus´ı to b´yt pˇresne´ jmeno typu).
´ r C++ ICP — Seminaˇ
132/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ´ ı Operatory pro pˇretypovan´
ˇ k TYP(v´ Doplnek yraz) (nepouˇz´ıvejte (TYP)v´ yraz ) const_cast < TYP > ( v´ yraz ) static_cast < TYP > ( v´ yraz ) reinterpret_cast < TYP > ( v´ yraz ) dynamic_cast < TYP > ( v´ yraz ) ´ Operatory static_cast, reinterpret_cast, const_cast ´ ı — vyjadˇruj´ı toteˇ ´ z co pˇredstavuj´ı specificke´ pˇretypovan´ ´ ı na private bazovou ´ (TYP)v´ yraz, kromeˇ pˇretypovan´ tˇr´ıdu. ´ ı. Jejich uˇ pˇretypovan´ ´ celem je explicitneˇ zv´yraznit umysl ´
´ r C++ ICP — Seminaˇ
133/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator const cast
const_cast(e) Pˇretypuje e na typ T pˇresneˇ jako (T)e za pˇredpokladu, zˇ e T a typ v´yrazu e se liˇs´ı pouze v const a volatile ´ modifikatorech a jde o ukazatel nebo referenci, jinak dojde ˇ k chybe. Nefunguje pro ukazatele na funkce a metody. ´ s puvodn Pouˇzit´ı v´ysledku pro praci eˇ konstantn´ımi daty ˚ ´ ´ ´ muˇ ˚ ze vest k nedefinovanemu chovan´ı. ´ ´ ı respektuj´ı ’konstantnost’ a Ostatn´ı operatory pˇretypovan´ ˇ nemohou ji menit.
´ r C++ ICP — Seminaˇ
134/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator static cast
static_cast(e) pˇretypuje e na typ T pokud: ˇ muˇ T pom(e); ˚ zeme deklarovat doˇcasnou promennou typ T je void ´ ı reference/ukazatele na (ne virtualn´ ´ ı) jde o pˇretypovan´ ´ bazovou tˇr´ıdu na referenci/ukazatel na odvozenou tˇr´ıdu existuje inverzn´ı standardn´ı konverze, int→enum, void*→Cls*, D::*p→B::*p ˇ jinak dojde k chybe.
´ r C++ ICP — Seminaˇ
135/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator reinterpret cast reinterpret_cast(e) pˇretypuje e na typ T kdyˇz jde o konverzi ukazatelu˚ na: celoˇc´ıseln´y typ nebo enum a naopak ´ funkce ruzn typu ˚ eho ´ objekty ruzn typu (i reference) ˚ eho ´ cˇ leny tˇr´ıd ruzn typu ˚ eho ˇ jinak dojde k chybe. Ukazatele a reference uvaˇzuje jako neupln ´ e´ typy (vztahy ´ ´ ´ ı). bazov a/odvozen a´ tˇr´ıda neovlivn´ı v´yznam pˇretypovan´ ´ Poznamka: V´ysledky reinterpret_cast se obvykle mus´ı ´ pˇretypovavat ´ ´ ı typ, aby byly pouˇzitelne. ´ dale na svuj ˚ originaln´ ´ r C++ ICP — Seminaˇ
136/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator reinterpret cast — pˇr´ıklad
void f(char *p) { *p = ’x’; } typedef void (*FP) (const char*); int main() { FP p = reinterpret_cast(&f); p("text"); // pozor - nemus´ ı fungovat (coredump) int *x=static_cast(malloc(9*sizeof(int))); long *y = reinterpret_cast(0x1FF0); // long *z = static_cast(0x1FF0); // chyba } ´ Poznamka: Minimalizovat pouˇzit´ı
´ r C++ ICP — Seminaˇ
137/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator dynamic cast dynamic_cast(v) ´ ı pˇretypovan´ ´ ı s kontrolou pˇri behu ˇ specialn´ programu. Typ T mus´ı b´yt ukazatel nebo reference na tˇr´ıdu nebo void*. Je-li T ukazatel a v je ukazatel na odvozenou tˇr´ıdu, potom ´ ı podobjekt. je v´ysledkem ukazatel na unikatn´ Je-li T reference a v objekt tˇr´ıdy odvozene´ z T, potom je ´ ı podobjekt. v´ysledkem reference na unikatn´ Kdyˇz T je typ void*, potom v mus´ı b´yt ukazatel a v´ysledek je ukazatel na kompletn´ı objekt. Jinak v mus´ı b´yt ukazatel nebo reference na polymorfn´ı typ ˇ a je provedena kontrola za behu programu, zda v muˇ ˚ ze b´yt ´ na typ T. Kdyˇz ne, operace skonˇc´ı neusp ˇ sneˇ konvertovan ´ eˇ ´ ´ ˇ – v´ysledna hodnota po pˇretypovan´ı bude 0, v pˇr´ıpade ´ reference je vyvolana v´yjimka bad_cast. ´ r C++ ICP — Seminaˇ
138/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Operator dynamic cast — pˇr´ıklad class B { // min. jedna virtu´ aln´ ı metoda virtual void m() {} }; class D : public B { // ... }; int main() { B *pb1 = new B; B *pb2 = new D;
// implicitn´ ı pˇ retypov´ an´ ı
D *pd1 = dynamic_cast(pb1); // 0 (nelze) D *pd2 = dynamic_cast(pb2); // uk. na objekt D } ´ r C++ ICP — Seminaˇ
139/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Sablony
”templates” sˇ ablony funkc´ı sˇ ablony tˇr´ıd = typy parametrizovane´ jin´ym typem ´ ı genericke´ programovan´ kl´ıcˇ ova´ slova: template, typename, export ´ cna´ specializace instanciace, specializace a cˇ asteˇ ´ ı, optimalizace, ”code bloat” ´ Poznamky: metaprogramovan´
´ r C++ ICP — Seminaˇ
140/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Sablony – pˇr´ıklady Deklarace template template
R f(T); class Vector;
ˇ Pouˇzit´ı sablon, instanciace int i = f(3.14); double d = f<double,double>(3); Vector vec; Vector< Vector > vec2; // pozor na >> std::map<std::string,int> m; std::basic_string us; ´ r C++ ICP — Seminaˇ
141/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Parametry sˇ ablon ˇ Sablony lze parametrizovat: typem — napˇr´ıklad class T nebo typename T hodnotou — napˇr´ıklad int i Lze pouˇz´ıt pouze celoˇc´ıselne´ typy, v´ycˇ et, ukazatel/referenci na objekt/funkci nebo ukazatel na cˇ len tˇr´ıdy. Odpov´ıdaj´ıc´ı argument mus´ı b´yt konstantn´ı v´yraz. sˇ ablonou — napˇr´ıklad template class K ˇ Sablona muˇ ˚ ze m´ıt v´ıce parametru: ˚ template< class T, T v, class U > class S;
´ r C++ ICP — Seminaˇ
142/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı Parametry sˇ ablon — pokraˇcovan´ Lze definovat implicitn´ı hodnoty parametru˚ sˇ ablon: template< typename T, int c = 10 > class S; template< template class p = S > class X; template< typename T, int size = 256 > class Buffer { /* definice */ }; // pouˇ zit´ ı: Buffer buf1; Buffer<std::string> buf2;
´ r C++ ICP — Seminaˇ
// kapacita 256
143/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Sablony funkc´ı
template T max(T x, T y) { // definice return (x>y)?x:y; } Pˇri prvn´ım pouˇzit´ı pˇrekladaˇc generuje odpov´ıdaj´ıc´ı funkci (instanci sˇ ablony) podle typu argumentu: ˚ MyClass a, b; int j = max(5,0); MyClass m = max(a,b);
// dedukce: max(5,0) // max<MyClass>(a,b)
ˇ Omezen´ı: Sablonu max lze pouˇz´ıt pro libovoln´y typ, kter´y ma´ ´ operator>, kop´ırovac´ı konstruktor a destruktor. definovan
´ r C++ ICP — Seminaˇ
144/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Sablony funkc´ı a funkce
Je moˇzne´ definovat dalˇs´ı funkce max, napˇr´ıklad: const char *max(const char *x, const char *y) { return (strcmp(x,y)>0) ? x : y; } const char *s = max("a", "aaa"); Potom ma´ tato funkce pˇrednost pˇred sˇ ablonou.
´ r C++ ICP — Seminaˇ
145/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı zˇ adn ´ e´ implicitn´ı konverze Pro genericke´ funkce se neprovad´ ´ ı: pole→ukazatel, ...): argumentu˚ (pouze trivialn´ void f(int i, char c) { max(i,i); // vol´ a max(int,int) max(c,c); // vol´ a max(char,char) max(i,c); // nen´ ı funkce max(int,char) =chyba! max(c,i); // nen´ ı max(char,int) =chyba! } Pokud bychom pˇredem explicitneˇ deklarovali funkci int max(int,int); ´ pˇr´ıpadeˇ se pouˇzije k chybeˇ by nedoˇslo, protoˇze v takovem konverze char na int. ´ Poznamka: Parametry sˇ ablony lze dedukovat pouze podle argumentu. ˚ ´ r C++ ICP — Seminaˇ
146/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Sablony tˇr´ıd — pˇr´ıklad Vector template class Vector { T * data; int size; public: Vector(int); //... }; template Vector::Vector(int n) { // definice konstruktoru } int main() { Vector x(5); // generuje instanci vektoru for(int i = 0; i<5; i++) x[i] = i; } ´ r C++ ICP — Seminaˇ
147/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Specializace sˇ ablon ´ ı pˇr´ıpady: Lze explicitneˇ definovat specialn´ // obecn´ a ˇ sablona: template T max(T x, T y) { return (x>y)?x:y; } // ˇ c´ asteˇ cn´ a specializace: template T* max(T*a, T*b) { /*...*/ } // specializace: template<> char* max(char*a, char*b) { /*...*/ }; template<> int* max<>(int*a, int*b) { /*...*/ } template<> void* max(void*a, void*b) { /*...*/ } // Vector - obecn´ a ˇ sablona: viz pˇ redch´ azej´ ıc´ ı slajdy // ˇ c´ asteˇ cn´ a specializace: template class Vector { /*...*/ }; // specializace: template<> class Vector { /*...*/ }; ´ r C++ ICP — Seminaˇ
148/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Specializace sˇ ablon
´ Specializace mus´ı nasledovat aˇz po definici obecne´ sˇ ablony ´ ı automatickemu ´ ´ ren´ı Definovane´ specializace zabran´ vytvaˇ instanc´ı z obecne´ sˇ ablony Pouˇzije se vˇzdy nejv´ıce specializovan´y pˇr´ıpad: Vector v1; // obecn´ a ˇ sablona Vector Vector v2; // ˇ c´ asteˇ cn´ a specializace Vector v3; // specializace Vector ´ ˇ sinou nelze pouˇz´ıt bez Identifikator sˇ ablony (Vector) vetˇ ˇ specifikace parametru sˇ ablony <> (kromeˇ nekter´ ych pˇr´ıpadu˚ uvnitˇr popisu sˇ ablony).
´ r C++ ICP — Seminaˇ
149/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: Seznam s typovou kontrolou 1 ´ ´ Problemem nasleduj´ ıc´ı implementace seznamu je nemoˇznost ´ typove´ kontroly vkladan´ ych prvku. ˚ class Glist { // data public: void insert(void *); void *get(); // ... }; ´ Poznamka: Heterogenn´ı seznam ( void* )
´ r C++ ICP — Seminaˇ
150/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: Seznam s typovou kontrolou 2 ˇ ı typove´ kontroly dosahneme ´ Doplnen´ takto: template class List : public Glist { public: void insert(T *t) { Glist::insert(t); } T *get() { return (T *)Glist::get(); } // ... }; ´ programu a je pˇritom velmi Vyuˇzit´ı tohoto pˇr´ıstupu zkracuje kod efektivn´ı (v tomto pˇr´ıpadeˇ typova´ kontrola nic nestoj´ı, protoˇze ´ ı se negeneruje zˇ adn´ ´ y kod ´ a metody jsou inline). na pˇretypovan´
´ r C++ ICP — Seminaˇ
151/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Poznamky ˇ Sablony lze definovat budˇ v hlaviˇckov´ych souborech, nebo s vyuˇzit´ım export pouze deklarovat a definici pˇreloˇzit jako samostatne´ moduly (zdaleka ne vˇsechny pˇrekladaˇce to podporuj´ı). Kaˇzda´ instance sˇ ablony ma´ svoje staticke´ prvky. Je moˇzne´ definovat sˇ ablony metod (vˇcetneˇ konstruktoru). ˚ ´ typu z´ıskaneho ´ z parametru Pro specifikaci, zˇ e jde o jmeno sˇ ablony se pouˇz´ıva´ kl´ıcˇ ove´ slovo typename: template class X { typedef typename T::TypeU U; // vnoˇ ren´ y typ public: int m(U o); }; ´ r C++ ICP — Seminaˇ
152/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Poznamky
Explicitn´ı instanciace ma´ tvar template deklarace: template class Vector; Knihovna STL (Standard Template Library), je cela´ ´ postavena na vyuˇzit´ı sˇ ablon. Tato knihovna tvoˇr´ı zaklad standardn´ı knihovny jazyka ISO C++. ˇ Pouˇzit´ı sˇ ablon umoˇznuje nove´ pˇr´ıstupy — genericke´ ´ ı, metaprogramovan´ ´ ı, ruzn programovan´ ˚ e´ optimalizace, atd. ´ eˇ ˇ r stejn´ych vec´ ˇ ı, je Vˇzdy, kdyˇz potˇrebujeme mnoho tem v´yhodne´ pouˇz´ıt sˇ ablony tˇr´ıd nebo funkc´ı.
´ r C++ ICP — Seminaˇ
153/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Obsluha v´yjimek ˇ Obsluha chyb vznikaj´ıc´ıch pˇri behu programu — tradiˇcn´ı pˇr´ıstupy: 1 2 3
4
Ukonˇcen´ı programu ´ Vracen´ ı hodnoty, ktera´ reprezentuje chybu (napˇr. fopen) ´ ´ ı hodnoty a ponechan´ ´ ı programu Vracen´ ı legaln´ ´ em ´ stavu (nevyhovuj´ıc´ı) v nespravn ´ ı specialn´ ´ ı funkce, ktera´ chyby oˇsetˇr´ı (napˇr. matherr) Volan´
ˇ C++ umoˇznuje strukturovane´ ˇreˇsen´ı v´yjimeˇcn´ych situac´ı: try throw catch
´ r C++ ICP — Seminaˇ
— vymezen´ı obsluhovane´ oblasti ´ ı v´yjimky — generovan´ — zachycen´ı v´yjimky
154/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: tˇr´ıda Vector s kontrolou mez´ı indexu class Vector { int *p; int sz; public: class Range {};
// typ v´ yjimky
int &operator[] (int i) { if(i>=0 && i<sz) return p[i]; else throw Range(); // vznik v´ yjimky } // ... }; ´ r C++ ICP — Seminaˇ
155/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: tˇr´ıda Vector s kontrolou mez´ı indexu 2a void f(Vector &v) { // ... try { // "hl´ ıdan´ a" oblast v[x] = 5; f2(); // ... } catch(Vector::Range) { // obsluha v´ yjimky Vector::Range // tento k´ od se provede jen kdyˇ z se // v sekci try vyskytne index mimo rozsah } // ... } ´ r C++ ICP — Seminaˇ
156/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Pˇr´ıklad: tˇr´ıda Vector s kontrolou mez´ı indexu 2b
void f(Vector &v) try { // "hl´ ıdan´ a" oblast je cel´ a funkce v[x] = 5; f2(); // ... } catch(Vector::Range) { // obsluha v´ yjimky Vector::Range // tento k´ od se provede jen kdyˇ z se // v sekci try vyskytne index mimo rozsah }
´ r C++ ICP — Seminaˇ
157/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Rozliˇsen´ı v´yjimek
Pˇr´ıkaz catch muˇ ˚ ze m´ıt parametr typu T, const T, T&, nebo const T& . Takov´y pˇr´ıkaz zachyt´ı v´yjimky: ´ stejneho typu ´ typu pro kter´y je T public bazovou tˇr´ıdou je-li T ukazatel, v´yjimka mus´ı b´yt typu ukazatel, kter´y lze zkonvertovat standardn´ı konverz´ı na T
´ r C++ ICP — Seminaˇ
158/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Pˇr´ıklad: tˇr´ıda Vector s kontrolou indexu a rozmeru class Vector { int *p; int sz; public: enum { max = 32000 }; class Range {}; // v´ yjimka - rozsah indexu class Size {}; // v´ yjimka - chybn´ a velikost Vector(int size) { if(size<0 || size>max) throw Size(); // ... } int &operator[] (int i); };
´ r C++ ICP — Seminaˇ
159/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ Pˇr´ıklad: tˇr´ıda Vector s kontrolou indexu a rozmeru void f() try { use_vectors(); // pouˇ zit´ ı tˇ r´ ıdy Vector } catch(Vector::Range) { // obsluha v´ yjimky Vector::Range } catch(Vector::Size) { // obsluha v´ yjimky Vector::Size } ´ Poznamka: Funkce f nemus´ı obsluhovat vˇsechny moˇzne´ ´ ı je moˇzne´ provest ´ ve funkc´ıch, v´yjimky — jejich zpracovan´ ktere´ ji zavolaly. ´ Poznamka: Obsluhu v´yjimek lze vnoˇrovat, tj. v obsluze v´yjimky muˇ ˚ ze b´yt dalˇs´ı blok try. ´ r C++ ICP — Seminaˇ
160/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
V´yjimky s parametry V´yjimky mohou obsahovat uˇziteˇcne´ informace: class Vector { // ... public: struct Range { // tˇ r´ ıda v´ yjimky int index; // hodnota chybn´ eho indexu Range(int i): index(i) {} }; int &operator[] (int i) { if(i>=0 && i<sz) return p[i]; throw Range(i); // pˇ red´ an´ ı hodnoty } // .... }; ´ ı ....pokraˇcovan´ ´ r C++ ICP — Seminaˇ
161/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı V´yjimky s parametry — pokraˇcovan´
void f(Vector &v) try { // ’hl´ ıdan´ a’ oblast - cel´ a funkce v[x] = 5; // .... } catch(Vector::Range r) { cerr << "chybn´ y index" << r.index << ’\n’ ; // ... }
´ r C++ ICP — Seminaˇ
162/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı v´yjimek Sdruˇzovan´ Je moˇzne´ definovat hierarchie v´yjimek — napˇr: class class class class
Matherr {}; Overflow: public Matherr {}; Underflow: public Matherr {}; Zerodivide: public Matherr {};
// // // //
b´ azov´ a tˇ r´ ıda pˇ reteˇ cen´ ı podteˇ cen´ ı dˇ elen´ ı nulou
void f() try { // ... } catch(Overflow) { // obsluha v´ yjimek typu Overflow a odvozen´ ych } catch(Matherr) { // vˇ sechny ostatn´ ı odvozen´ e z Matherr } ´ r C++ ICP — Seminaˇ
163/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı v´yjimek Sdruˇzovan´
´ ı obsluhy v´yjimek prob´ıha´ v poˇrad´ı, ve Vyhodnocovan´ ´ jsou uvedeny pˇr´ıkazy catch. kterem Obsluha v´yjimky typu T zpracuje i vˇsechny v´yjimky odvozene´ z T Vˇsechny jeˇsteˇ neobslouˇzene´ v´yjimky je moˇzno zpracovat v sekci catch(...)
´ r C++ ICP — Seminaˇ
164/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ an´ ´ ı zdroju˚ Pˇridelov
Tradiˇcn´ı ˇreˇsen´ı: void use_file(const char *jmeno) { // pouˇ zit´ ı souboru FILE *f = fopen(jmeno,"r"); // otevˇ ren´ ı // pouˇ zit´ ı souboru f fclose(f); // uzavˇ ren´ ı } V pˇr´ıpadeˇ v´yskytu v´yjimky uvnitˇr funkce je pˇreskoˇcen pˇr´ıkaz fclose a soubor zustane otevˇren! ˚
´ r C++ ICP — Seminaˇ
165/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ an´ ´ ı zdroju˚ 2 Pˇridelov ´ ı (a nevhodne) ´ ˇreˇsen´ı: Trivialn´ void use_file(const char *jmeno) { FILE *f = fopen(jmeno,"r"); try { // pouˇ zit´ ı souboru f } catch(...) { // pro vˇ sechny v´ yjimky ... fclose(f); // uzavˇ re soubor throw; // znovu vyvol´ a tut´ eˇ z v´ yjimku // (poˇ sle ji volaj´ ıc´ ı funkci) } fclose(f); }
´ r C++ ICP — Seminaˇ
166/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ sen´ı pˇridelov ˇ an´ ´ ı zdroju˚ inicializac´ı Reˇ
´ ıch objektu: Zdroje ve formeˇ lokaln´ ˚ ˇ ı zdroje = inicializace (volan´ ´ ı konstruktoru) pˇridelen´ ˇ ı (volan´ ´ ı destruktoru) automaticke´ uvolnen´
´ r C++ ICP — Seminaˇ
167/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
ˇ an´ ´ ı zdroju˚ = inicializace (pˇr´ıklad) Pˇridelov class FilePtr { // chov´ a se stejnˇ e jako FILE* FILE *p; public: FilePtr(const char *name, const char *atr) { p = fopen(name,atr); } ~FilePtr() { fclose(p); } operator FILE*() { return p; } } void use_file(const char *jmeno) { FilePtr f(jmeno,"r"); // otevˇ ren´ ı souboru // pouˇ zit´ ı souboru f } // automatick´ e uzavˇ ren´ ı souboru ´ r C++ ICP — Seminaˇ
168/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Konstruktory, destruktory a v´yjimky ´ destruktory vˇsech Pˇri vzniku v´yjimky v konstruktoru jsou volany objektu, ˚ jejichˇz konstruktory byly bezchybneˇ dokonˇceny. ˇ an´ ´ ı pameti ˇ Pˇr´ıklad: pˇridelov class X { int *p; public: X(int s) { p = new int[s]; init(); } ~X() { delete [] p; } // ... }; ´ tˇr´ıdy nen´ı vhodne, ´ protoˇze pˇri v´yjimce vznikle´ Pouˇzit´ı teto v init() se nezavola´ destruktor, protoˇze nebyl kompletneˇ dokonˇcen konstruktor. ´ r C++ ICP — Seminaˇ
169/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Bezpeˇcne´ ˇreˇsen´ı: template class MemPtr { T *p; public: MemPtr(size_t s) { p = new T[s]; } ~MemPtr() { delete [] p; } operator T* () { return p; } }; class X { MemPtr cp; // ukazatel - objekt public: X(int s): cp(s) { init(); } }; ˇ ı pameti. ˇ V´yjimka v init() vˇzdy vede ke korektn´ımu uvolnen´ ´ Poznamka: std::auto_ptr, shared_ptr ´ r C++ ICP — Seminaˇ
170/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Specifikace rozhran´ı v´yjimek ´ Specifikace mnoˇziny v´yjimek, ktere´ mohou b´yt funkc´ı vyvolany. Pˇr´ıklad specifikace void f() throw (x2,x3); specifikuje, zˇ e funkce f muˇ ˚ ze vyvolat v´yjimky x2 a x3 ´ avˇsak zˇ adn ´ e´ jine. ´ (a vˇsechny odvozene), Funkce bez specifikace muˇ ˚ ze vyvolat jakoukoli v´yjimku: int f(); // m˚ uˇ ze vyvolat libovolnou v´ yjimku ´ ´ Funkce, ktera´ nebude vyvolavat zˇ adnou v´yjimku: int g() throw(); ´ ı typu funkce. ´ Poznamka: Specifikace v´yjimek nen´ı souˇcast´
´ r C++ ICP — Seminaˇ
171/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Specifikace rozhran´ı v´yjimek Funkce void f() throw (x2,x3) { // k´ od funkce } je ekvivalentn´ı funkci void f() try { // k´ od funkce } catch(x2) { throw; } // v´ yjimka pokraˇ cuje catch(x3) { throw; } catch(...) { unexpected(); // chybov´ e ukonˇ cen´ ı programu } ´ r C++ ICP — Seminaˇ
172/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Specifikace rozhran´ı v´yjimek
´ Poznamky: ´ ı metody mus´ı m´ıt vˇsechny metody, ktere´ ji U virtualn´ ´ ı v odvozen´ych tˇr´ıdach, ´ pˇredefinovavaj´ specifikaci stejnou nebo v´ıce omezuj´ıc´ı moˇzne´ v´yjimky. Do ukazatele na funkci, ktera´ specifikuje v´yjimky, lze pˇriˇradit ukazatel na funkci, ktera´ ma´ specifikaci stejnou nebo v´ıce omezuj´ıc´ı moˇzne´ v´yjimky.
´ r C++ ICP — Seminaˇ
173/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Neoˇcekavan e´ v´yjimky ˇ ı v´yznam volan´ ´ ı Existuje funkce set_unexpected, ktera´ men´ funkce unexpected typedef void(*PFV)(); PFV set_unexpected(PFV); class STC { PFV old; public: STC(PFV f) { old = set_unexpected(f); } ~STC() { set_unexpected(old); } }; void rethrow() { throw; } void g2() { STC xx(&rethrow); // unexpected() bude volat rethrow() g(); // p˚ uvodn´ ı funkce } ´ r C++ ICP — Seminaˇ
174/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ´ Neoˇcekavan e´ v´yjimky — poznamky
pokud by se rethrow nevolalo z catch(...), doˇslo by ´ ı funkce terminate k vyvolan´ unexpected se nikdy nevrac´ı (mus´ı vyvolat v´yjimku, nebo terminate()) ... ´ ı Neopatrneˇ pouˇzite´ specifikace v´yjimek vedou k volan´ ´ funkce unexpected, coˇz je obvykle neˇzadouc´ ı. Lze tomu ´ pˇredchazet peˇclivou organizac´ı v´yjimek: napˇr´ıklad ´ Y by mel ˇ m´ıt vˇsechny v´yjimky odvozene´ podsystem ´ z bazov e´ tˇr´ıdy Yerr.
´ r C++ ICP — Seminaˇ
175/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Neobslouˇzene´ v´yjimky ´ ym pˇr´ıkazem catch Nen´ı-li v´yjimka obslouˇzena zˇ adn´ ´ je volana funkce terminate, ktera´ ukonˇc´ı program. ´ ı terminate() lze pˇredefinovat funkc´ı Efekt volan´ set_terminate: typedef void(*PFV)(); // ukazatel na funkci PFV set_terminate(PFV); Implicitneˇ plat´ı, zˇ e unexpected() vola´ terminate() a terminate() vola´ abort() ˇ s´ı kod, ´ vlastn´ı ´ Poznamka: Pouˇzit´ı v´yjimek vede na vetˇ ´ ı v´yjimky je pomale. ´ vyvolan´
´ r C++ ICP — Seminaˇ
176/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Standardn´ı v´yjimky
<exception>: class exception class bad_exception
b´ aze pro std v´ yjimky
: class bad_alloc : class bad_cast class bad_typeid
´ r C++ ICP — Seminaˇ
177/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı Standardn´ı v´yjimky — pokraˇcovan´ <stdexcept>: class logic_error logick´ e chyby class domain_error class invalid_argument class length_error class out_of_range class runtime_error chyby pˇ ri bˇ ehu programu class range_error class overflow_error class underflow_error ´ metodu ktera´ vrac´ı ˇretezec ˇ Vˇsechny tyto tˇr´ıdy maj´ı definovanu s popisem v´yjimky: virtual const char* what() const throw(); ´ r C++ ICP — Seminaˇ
178/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ˇ cnost Nasobn a´ dediˇ ˇ en´ ˇ ı z nekolika ˇ ´ ˇ Ded bazov´ ych tˇr´ıd souˇcasne: class C : public A, public B { // ˇ cleny tˇ r´ ıdy }; hierarchie tˇ r´ ıd:
A
B
C ´ r C++ ICP — Seminaˇ
objekt:
a b c 179/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ˇ cnost Nasobn a´ dediˇ
´ Poznamky: ´ ı Poˇrad´ı tˇr´ıd v deklaraci nen´ı v´yznamne´ kromeˇ poˇrad´ı volan´ ˇ konstruktoru, ˚ destruktoru˚ a uloˇzen´ı v pameti. Pozor na konverze ukazatelu! ˚ ´ ˇ cnosti: lodˇ + letadlo = hydroplan ´ Pouˇzit´ı nasobn e´ dediˇ Souvislosti: Java interface, private, ...
´ r C++ ICP — Seminaˇ
180/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ˇ cnost — moˇzne´ problemy ´ Nasobn a´ dediˇ Moˇzna´ nejednoznaˇcnost: ´ dveˇ bazov e´ tˇr´ıdy maj´ı stejneˇ pojmenovan´y cˇ len — jejich pouˇzit´ı lze rozliˇsit kvalifikac´ı. Pˇr´ıklad A::i nebo B::i ˇ dvakrat ´ tuteˇ ´ z tˇr´ıdu lze jen nepˇr´ımo: Dedit class class class class
X { .... }; // b´ azov´ a tˇ r´ ıda A : X { .... }; B : X { .... }; C : A,B { .... };
Tˇr´ıda C obsahuje dveˇ instance tˇr´ıdy X.
´ r C++ ICP — Seminaˇ
181/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ˇ cnost — virtualn´ ´ ı baze ´ Nasobn a´ dediˇ
class class class class
X { .... }; A : virtual X { .... }; B : virtual X { .... }; C : A,B { .... };
Tˇr´ıda C obsahuje pouze jednu instanci tˇr´ıdy X. ´ ı ´ Poznamka: Moˇznost parametrizace konstruktoru virtualn´ ´ bazov e´ tˇr´ıdy X: C::C(): X(1), A(2), B(3) { .... }
´ r C++ ICP — Seminaˇ
182/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı konstruktoru˚ a nasobn ´ ˇ cnost Poˇrad´ı volan´ a´ dediˇ ´ ´ pˇred proveden´ım Konstruktory bazov´ ych tˇr´ıd jsou volany ´ konstruktoru dane´ tˇr´ıdy v poˇrad´ı deklarace bazov´ ych tˇr´ıd v hlaviˇcce tˇr´ıdy. ´ ıch bazov´ ´ ´ pˇred Konstruktory virtualn´ ych tˇr´ıd jsou vyvolany ´ ıch bazov´ ´ konstruktory nevirtualn´ ych tˇr´ıd (je-li jich v´ıce volaj´ı se v poˇrad´ı jejich uveden´ı v deklaraci). ´ ze virtualn´ ´ ı bazov ´ Je-li v hierarchii tˇr´ıd v´ıce instanc´ı teˇ e´ ´ pouze jednou. tˇr´ıdy je jej´ı konstruktor volan ´ ´ ı i nevirtualn´ ´ ı, potom Jsou-li instance bazov e´ tˇr´ıdy virtualn´ ´ jednou pro vˇsechny instance virtualn´ ´ ı je konstruktor volan ´ ı — destruktory a jednou pro kaˇzdou instanci nevirtualn´ ´ v pˇresneˇ obracen ´ ´ poˇrad´ı neˇz jim jsou volany em odpov´ıdaj´ıc´ı konstruktory. ´ r C++ ICP — Seminaˇ
183/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Ukazatele na cˇ leny tˇr´ıd ˇ zne´ ukazatele, nelze na neˇ aplikovat beˇ ˇ zna´ pravidla Nejde o beˇ ´ pro pˇretypovan´ı, nelze je konvertovat na void * ´ operator prvn´ı operand druh´y operand .* objekt tˇr´ıdy T nebo ukazatel na cˇ len tˇr´ıdy T odvozene´ tˇr´ıdy ->* ukazatel na objekt tˇr´ıdy T ukazatel na cˇ len tˇr´ıdy T nebo odvozene´ Pˇr´ıklad deklarace ukazatele na metodu void (T::*ptr)(int) = &T::metoda2; // inicializace Metoda mus´ı b´yt kompatibiln´ı s ukazatelem.
´ r C++ ICP — Seminaˇ
184/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Ukazatele na cˇ leny tˇr´ıd — pˇr´ıklad T objekt; T *ukazatel_na_objekt = &objekt; int main() { int (T::*p1)(); p1 = &T::Metoda1; // pˇ riˇ razen´ ı (objekt.*p1)(); p1 = &T::Metoda5; // pˇ riˇ razen´ ı (objekt.*p1)(); void (T::*const p2)(int) = &T::Metoda2; // init (ukazatel_na_objekt->*p2)(parametr); } ´ operator ´ u˚ je nutne´ pouˇz´ıvat ´ Poznamka: Vzhledem k prioritam ´ zavorky. ´ r C++ ICP — Seminaˇ
185/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ Ukazatele na cˇ leny tˇr´ıd — poznamky
´ Poznamky: ´ Jestliˇze v´ysledkem operatoru .* nebo ->* je metoda, ´ potom jej lze pouˇz´ıt pouze jako operand pro operator (). ´ an´ ´ ı ukazatele na metodu jako Pouˇzit´ı — napˇr´ıklad pˇredav parametru funkce.
´ r C++ ICP — Seminaˇ
186/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ´ u˚ .* a ->* — pˇr´ıklad Zaklady pouˇzit´ı operator struct A { int i; void M() { i = 0; } }; void (A::*u1)(); int (A::*u2); int main() { A a; A *u = &a; u1 = &A::M; // ukazatel na metodu M u2 = &A::i; (a.*u1)(); // vol´ an´ ı metody objektu a (u->*u1)(); // vol´ an´ ı pˇ res ukazatel na objekt a.*u2 = 5; // pˇ riˇ razen´ ı do a.i } ´ r C++ ICP — Seminaˇ
187/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Prostory jmen (”namespaces”)
definice-prostoru-jmen: namespace identifik´ atoropt { seznam-deklarac´ ı } alias-definice-prostoru-jmen: namespace identifik´ ator = jm´ eno-prostoru ; jm´ eno-prostoru: ::opt identifik´ ator jm´ eno-prostoru :: identifik´ ator
´ r C++ ICP — Seminaˇ
188/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Prostory jmen (namespaces)
definice se mohou opakovat ´ ´ ı (nesm´ı se shodovat se jmenem ´ jmeno mus´ı b´yt unikatn´ tˇr´ıdy, objektu, typu, ...) definice prostoru jmen je deklarac´ı prostory jmen lze vnoˇrovat existuje nepojmenovan´y prostor jmen ´ ana ´ funkce deklarovana´ jako extern "C" je svaz s C funkc´ı bez kvalifikace: namespace X { extern "C" void f(); }
´ r C++ ICP — Seminaˇ
// C-funkce f()
189/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Definice a pouˇzit´ı prostoru jmen namespace A { class String { /* ... */ }; void f(String); } namespace B { class String { /* ... */ }; void f(String); } void g() { A::String s; // explicitn´ ı kvalifikace A::f(s); } ´ r C++ ICP — Seminaˇ
190/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Definice a pouˇzit´ı prostoru jmen
ˇ Cleny prostoru jmen lze definovat vneˇ tohoto prostoru: void A::f(String s) { String ss = "aaa"; // ... }
// A::String // A::String
´ Poznamka: extern, friend funkce
´ r C++ ICP — Seminaˇ
191/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Using deklarace a direktivy using-deklarace: using jm´ eno-prostoru :: identifik´ ator ; using-direktiva: using namespace jm´ eno-prostoru ; using deklarace nen´ı definic´ı (jsou dovoleny redundantn´ı deklarace) void h() { using A::String; using A::f; String s; f(s);
// A::String // A::f
} ´ r C++ ICP — Seminaˇ
192/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
´ ı Using deklarace a direktivy — pokraˇcovan´
´ a´ nova´ jmena ´ using direktiva nedeklaruje zˇ adn (pouze je zpˇr´ıstupn´ı) void k() { using namespace A; String s; // A::String f(s); // A::f } ´ using direktiva neovlivn´ı jiˇz deklarovana´ jmena
´ r C++ ICP — Seminaˇ
193/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Tˇr´ıdy a prostory jmen ´ ı jmen je tˇr´ıda prostorem jmen pro uˇ ´ cely hledan´ using lze aplikovat stejneˇ jako u prostoru jmen class B { public: virtual void f(int); virtual void f(double); // ... }; class C : protected B { public: using B::f; // B::f(int), B::f(double) dostupn´ e virtual void f(int); // pˇ rekryt´ ı B::f(int) virtual void f(char); // nov´ e f(char) // ... }; ´ r C++ ICP — Seminaˇ
194/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Tˇr´ıdy a prostory jmen
using deklarace pouˇzita´ uvnitˇr tˇr´ıdy jako cˇ lenska´ deklarace ´ mus´ı odkazovat na pˇr´ıstupne´ cˇ leny bazov´ ych tˇr´ıd using direktiva nemuˇ ˚ ze b´yt pouˇzita jako cˇ lenska´ deklarace uvnitˇr tˇr´ıdy nelze definovat prostor jmen ˇ do v´ıce deklarac´ı prostor jmen tˇr´ıd nelze rozdelit
´ r C++ ICP — Seminaˇ
195/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Nepojmenovan´y prostor jmen Symboly nejsou dostupne´ z jin´ych modulu˚ (jako static v C). namespace { void f(); } void g() { f(); }
// pˇ r´ ıstupn´ e pouze z aktu´ aln´ ıho modulu
// extern´ ı funkce pˇ r´ ıstupn´ a vˇ sude
´ Poznamky: ´ ı tˇr´ıdu pameti ˇ static, ale V C++ nepouˇz´ıvat globaln´ nepojmenovan´y prostor jmen Nepouˇz´ıvat zastarale´ deklarace pˇr´ıstupu uvnitˇr tˇr´ıd, ale using deklarace ´ r C++ ICP — Seminaˇ
196/211
´ Uvod Jazyk Knihovny
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony Pˇrehled Objekty Pˇreteˇ V´yjimky
Kl´ıcˇ ove´ slovo mutable ´ mutable — muˇ na cˇ leny tˇr´ıdy bez specifikace ˚ ze b´yt aplikovano const nebo static. Takto oznaˇcen´y cˇ len tˇr´ıdy nen´ı nikdy konstantn´ı — a to ani uvnitˇr konstantn´ıho objektu. class T { mutable unsigned refcount; int data; public: T(): refcount(0), data(0) {} const T * ref() const { refcount++; return this; } void setdata(int n) { data = n; } }; const T o; const T * g() { o.setdata(4); // chyba: nelze modifikovat const return o.ref(); // modifikace konstantn´ ıho objektu } ´ r C++ ICP — Seminaˇ
197/211
´ Uvod Jazyk Knihovny
Boost
Standardn´ı knihovny ´ Direktiva #include nevyˇzaduje pˇr´ıponu jmena souboru ISO C++ zahrnuje standardn´ı knihovny ISO C90: rozhran´ı co obsahuje ˇ ı. Makro assert pro laden´ Makra pro klasifikaci znaku. ˚ ´ konstanty – chybove´ kody Parametry pro floating-point podpora omezen´ych zn. sad rozsahy cel´ych cˇ ´ısel ´ narodn´ ı/jazykova´ podpora Matematicke´ funkce. Typy pro longjmp() a setjmp(). deklarace pro signal() a raise()
´ r C++ ICP — Seminaˇ
198/211
´ Uvod Jazyk Knihovny
Boost
Standardn´ı knihovna C rozhran´ı
co obsahuje ´ s promenn´ ˇ ym poˇctem argumentu˚ prace ˇ Nekter a´ makra a datove´ typy. Definice pro standardn´ı vstup/v´ystup Obecneˇ pouˇzitelne´ funkce ´ s ˇretezci ˇ ˇ ı. Funkce pro praci a pamet´ ´ s cˇ asem. Typy a funkce pro praci ´ s wchar_t prace makra pro klasifikaci wchar_t
ˇ v prostoru jmen std. Vˇsechny definice jsou um´ısteny Podrobnosti — viz Jazyk C
´ r C++ ICP — Seminaˇ
199/211
´ Uvod Jazyk Knihovny
Boost
Pˇrehled standardn´ı knihovny C++ 1/3 rozhran´ı <deque> <exception> ´ r C++ ICP — Seminaˇ
co obsahuje algoritmy ´ posloupnost bitu˚ pevne´ delky komplexn´ı cˇ ´ısla ˇ a´ fronta obousmern obsluha v´yjimek - unexpected, terminate soubory - vstup/v´ystupn´ı streamy ´ ı, binarn´ ´ ı) funkˇcn´ı objekty (unarn´ ´ manipulatory pro streamy ´ bazov a´ tˇr´ıda pro streamy forward deklarace pro streamy vstup/v´ystupn´ı streamy vstupn´ı streamy ´ iteratory 200/211
´ Uvod Jazyk Knihovny
Boost
Pˇrehled standardn´ı knihovny C++ 2/3 rozhran´ı <list> <map> <memory> <set> <sstream> <stack>
´ r C++ ICP — Seminaˇ
co obsahuje implementaˇcn´ı limity - mezn´ı hodnoty typu˚ seznam ´ lokalizace - narodn´ ı abecedy, isalpha, ... asociativn´ı kontejner - kl´ıcˇ -hodnota ´ pameti ˇ - alokator, ´ sprava ... ´ ´ ˇ sprava dynamicke pameti numericke´ operace (accumulate,...) v´ystupn´ı streamy fronta asociativn´ı kontejner - mnoˇzina kl´ıcˇ u˚ ˇretezcov ˇ e´ streamy ´ zasobn´ ık
201/211
´ Uvod Jazyk Knihovny
Boost
Pˇrehled standardn´ı knihovny C++ 3/3 rozhran´ı <stdexcept> <streambuf> <string>
co obsahuje standardn´ı typy v´yjimek ´ vyrovnavac´ ı pameˇ ˇt pro streamy ˇ obecne´ ˇretezce (basic_string, ...) typove´ informace - tˇr´ıda type_info relaˇcn´ı operace pole hodnot vektor
ˇ v prostoru jmen std. Vˇsechny definice jsou um´ısteny ´ ´ Poznamka: STL — Standard Template Library — je zaklad ´ pro definice kontejneru, ˚ iteratoru, ˚ algoritmu, ˚ atd.
´ r C++ ICP — Seminaˇ
202/211
´ Uvod Jazyk Knihovny
Boost
Knihovny pro C++ ´ e´ pˇrehledy dalˇs´ıch knihoven Na Internetu jsou dostupne´ rozsahl ˇ ı to, co nen´ı ve standardn´ı knihovneˇ pro C/C++ ktere´ doplnuj´ ISO C++: Grafika, GUI S´ıˇtova´ rozhran´ı ´ ı, vlakna ´ Paraleln´ı programovan´ Numericke´ metody ´ ı Metaprogramovan´ ´ ı textu Zpracovan´ ´ ı Testovan´ ...
´ r C++ ICP — Seminaˇ
203/211
´ Uvod Jazyk Knihovny
Boost
Boost http://www.boost.org/ C´ıl: testovat nove´ knihovny aby se mohly zaˇradit do pˇr´ısˇ t´ı verze normy ISO C++. Zahrnuje celou ˇradu rozˇsiˇruj´ıc´ıch knihoven pro C++: ´ ı v´yrazy (regex), LL parser (spirit) regularn´ ´ vlakna (thread), s´ıˇtova´ komunikace (asio, MPI) ´ pseudonahodn a´ cˇ ´ısla (random), ruzn ˚ a´ rozloˇzen´ı matematika (math, uBLAS, quaternion, rational, ...) ´ ı obrazu (GIL) zpracovan´ datove´ struktury (graph, array, circular buffer, dynamic bitset, ...) ´ n-tice, smart ptr, souborov´y system, datum a cˇ as, intervaly, lambda, ´ ´ ı (MPL), navrhov e´ vzory (flyweight), metaprogramovan´ serializace ... ´ r C++ ICP — Seminaˇ
204/211
´ Uvod Jazyk Knihovny
Boost
Boost — TODO: zkontrolovat ˇ ´ Nekter e´ knihovny jsou jiˇz schvaleny (TR1): ´ array — obalka pro pole (ve stylu STL) ˇ ı std::bind1st a bind2nd bind — zobecnen´ function — funkˇcn´ı objekty (callback) hash, unordered — rozptylovac´ı funkce + kontejnery ˇ ı std::mem_fun a member function — zobecnen´ mem_fun_ref ´ random — pseudonahodn a´ cˇ ´ısla ´ an´ ´ ı referenc´ı do sˇ ablon ref — pˇredav ´ ı v´yrazy regex — regularn´ smart ptr — shared_ptr, weak_ptr, ... tuple — n-tice ´ (is_class, ...) type traits — pro testy v sˇ ablonach ´ ´ Poznamka: vlakna (thread) ´ r C++ ICP — Seminaˇ
205/211
´ Uvod Jazyk Knihovny
Boost
Lambda – pˇr´ıklady
list v(10); for_each(v.begin(), v.end(), _1 = 1); // 1 do kaˇ zd´ eho prvku vector vp(10); transform(v.begin(), v.end(), vp.begin(), &_1); // napln´ ı vp ukazateli na prvky v int foo(int); // mus´ ıme m´ ıt funkci for_each(v.begin(), v.end(), _1 = bind(foo, _1)); // vol´ a funkci foo, zmˇ en´ ı kaˇ zd´ y prvek kontejneru sort(vp.begin(), vp.end(), *_1 > *_2); // ˇ rad´ ı vp - klesaj´ ıc´ ı velikost c´ ıl˚ u ukazatel˚ u for_each(vp.begin(), vp.end(), cout << *_1 << ’\n’); // v´ ystup c´ ıl˚ u ukazatel˚ u ´ r C++ ICP — Seminaˇ
206/211
´ Uvod Jazyk Knihovny
Boost
´ Lambda – problemy implementace for_each(vp.begin(), vp.end(), cout << ’\n’ << *_1); // probl´ em: cout << ’\n’ se vyhodnot´ ı jen jednou
for_each(vp.begin(), vp.end(), cout << constant(’\n’) << *_ // odloˇ zen´ e vyhodnocen´ ı A a; B b; (_1 + _2)(a, b); // chyba -- nelze dedukovat n´ avratov´ y typ A a; B b; ret(_1 + _2)(a, b); // ˇ reˇ sen´ ı int i = 1; int j = 2; (_1 + _2)(i, j); // ok (_1 + _2)(1, 2); // chyba, ale nevad´ ı - nepouˇ z´ ıv´ a se ´ r C++ ICP — Seminaˇ
207/211
´ Uvod Jazyk Knihovny
Boost
Pˇr´ıklady – n-tice (Tuples) n je omezeno implementac´ı (napˇr 0..10) tuple tuple<double&, const double&, const double, double*, const double*> tuple tuple<std::string, std::pair > tuple, bool, void*> // objekty: tuple() tuple(1) tuple(1, 3.14)
// default ctr
tuple add_multiply_divide(int a, int b) { return make_tuple(a+b, a*b, double(a)/double(b)); } ´ r C++ ICP — Seminaˇ
208/211
´ Uvod Jazyk Knihovny
Boost
n-tice
// pˇ r´ ıstup k prvk˚ um:
get(t)
double d = 2.7; A a; tuple t(1, d, a); get<1>(t) = 3.14; ++get<0>(t);
// ekvivalent d = 3.14 // O.K.
tuple x = std::make_pair(1,’a’); // konverze // operace < == > <= >= !=
´ r C++ ICP — Seminaˇ
(lexikografick´ e uspoˇ r´ ad´ an´ ı)
209/211
´ Uvod Jazyk Knihovny
Boost
´ ı n-tice Specialn´ int i; char c; double d; tie(i, c, a); // ekvivalent: make_tuple(ref(i), ref(c), ref(a)); // I/O tuple a(1.0f, 2, string("ahoj")); cout << a; // tiskne: (1.0 2 ahoj) // // // //
Manipul´ atory: set_open(char) set_close(char) set_delimiter(char)
´ r C++ ICP — Seminaˇ
( ) ’ ’
210/211
´ Uvod Jazyk Knihovny
Boost
Shrnut´ı
Dalˇs´ı pˇr´ıklady viz WWW ´ je vhodne´ se s nimi Knihovny v Boost jsou velmi pouˇzitelne, ´ ´ seznamit i kdyˇz ne vˇsechny budou standardizovany.
´ r C++ ICP — Seminaˇ
211/211