´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
´ Uvod
Literatura
´ r C++ Seminaˇ Petr Peringer peringer AT fit.vutbr.cz
ˇ 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´
Vysoke´ uˇcen´ı technicke´ v Brneˇ Fakulta informaˇcn´ıch technologi´ı, ˇ Boˇzetechova 2, 61266 Brno
(Verze 2015-02-09)
Pˇreloˇzeno: 10. unora 2015 ´
´ r C++ ICP — Seminaˇ
1/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
2/245
´ Uvod Jazyk Knihovny C++11
Literatura
Zdroje informac´ı
Literatura
Literatura Stroustrup, B.: The C++ programming language, 4th edition, Addison-Wesley, 2013 The C++ Standard: Incorporating Technical Corrigendum No.1, Wiley, 2003 (C++98)
Dobra´ literatura http://www.fit.vutbr.cz/study/courses/ICP/public/
C++11: Working Draft, Standard for Programming Language C++, http://www.open-std.org/jtc1/sc22/wg21/ /docs/papers/2012/n3337.pdf [2012-01-16]
WWW: FAQ, pˇrehledy knihoven ´ programu man (sekce 3) databaze GNU info a dalˇs´ı dokumentace
C++14: Working Draft, Standard for Programming Language C++, http://www.open-std.org/jtc1/sc22/wg21/ /docs/papers/2013/n3797.pdf [2013-10-13]
...
Gamma E. et al.: Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1994 ´ r C++ ICP — Seminaˇ
3/245
´ r C++ ICP — Seminaˇ
4/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Programovac´ı jazyk C++
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇrekladaˇce C++
Historie 1973 1980 1990 1998 1999 2003 2011 2011 2014
vznik jazyka C: Kernighan, Ritchie, (K&R C) ˇ C++: Bjarne Stroustrup vznik ”C with classes”- pozdeji ´ ISO C: mezinarodn´ ı norma (C90) ´ ISO C++: mezinarodn´ ı norma (C++98) ISO C: (C99) TC1: aktualizace normy C++ (C++03) ISO C++: norma C++ (C++11) ´ ı norma jazyka C (C11) ISO C: aktualn´ ´ ı norma C++ (C++14) ISO C++: aktualn´
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´ı od pouˇz´ıvat novejˇ normy.) ´ Poznamka: Integrovana´ prostˇred´ı (Eclipse,Netbeans,Anjuta,KDevelop,...) nebo editory (VIM,Emacs,...) + program make
Puvodn´ ı definic´ı je kniha Stroustrup: The C++ Programming ˚ Language (Addison-Wesley 1985, 1991, 1997, 2013). Plat´ı norma ISO/IEC 14882:2011. ´ a´ znalost jazyka ISO C ´ Poznamka: Tento text pˇredpoklad ´ r C++ ICP — Seminaˇ
5/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Charakteristika jazyka C++
6/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Nev´yhody C++
ˇ Obecneˇ vyuˇziteln´y programovac´ı jazyk vyˇssˇ ´ı urovn e. ´ ˇ s´ı a sloˇzitejˇ ˇ s´ı neˇz C Je podstatneˇ vetˇ Nen´ı cˇ isteˇ objektoveˇ orientovan´y (napˇr. typ int nen´ı tˇr´ıda a ˇ dedit) ˇ nelze z nej ˇ nekter ˇ ´ ´ ı pol´ı se Zdedil e´ problemy jazyka C (indexovan´ ´ ı sprava ´ pameti, ˇ ...) nekontroluje, manualn´
Je standardizovan´y (ISO) ´ ren´ı knihoven. Podporuje abstraktn´ı datove´ typy a vytvaˇ ´ ˇ a´ kompatibilita) Nastupce jazyka C (zpetn Vysoka´ efektivita ˇ cnost) Objektova´ orientace (tˇr´ıdy, dediˇ
Nen´ı zcela kompatibiln´ı s jazykem C (restrict, complex, ...) ˇ Ne vˇsechny pˇrekladaˇce dostateˇcneˇ vyhovuj´ı norme.
ˇ zovat operatory ´ Moˇznost pˇreteˇ Genericke´ tˇr´ıdy a funkce (ˇsablony) Obsluha v´yjimek
´ Poznamka: Citace z Internetu: ”There are only two kinds of programming languages: those people always bitch about and those nobody uses.”
´ Std. knihovna (kontejnery, vlakna, regexp, random, ...) Mnoho ruzn´ ˚ ych implementac´ı pˇrekladaˇcu˚ Mnoˇzstv´ı knihoven pro ruzn ˚ e´ aplikace (Boost, Qt, ...) ´ r C++ ICP — Seminaˇ
7/245
´ r C++ ICP — Seminaˇ
8/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ ı Optimalizace a laden´
Pˇreklad a sestaven´ı programu Soubor ahoj.cc: #include
// bez pˇ r´ ıpony int main() { std::cout << "Ahoj!\n"; // tisk ˇ retˇ ezce }
´ Optimalizace kodu pˇrekladaˇcem (UNIX, GNU C++): g++ -O2 -o prog
´ Poznamka: Nejlepˇs´ı urove nˇ optimalizace je tˇreba vyzkouˇset ´
´ ı (UNIX, pˇrekladaˇc GNU C++): Zpusob zpracovan´ ˚ g++ -o ahoj ahoj.cc ./ahoj
# pˇ reklad, sestaven´ ı # spuˇ stˇ en´ ı
clang++ -o ahoj ahoj.cc
# pˇ rekladaˇ c clang/LLVM
prog.cc
ˇ ı (Linux, GNU C++, GNU debugger): Laden´ g++ -g -o prog prog.cc gdb prog
# +ladic´ ı informace # ladˇ en´ ı v pˇ r´ ıkazov´ e ˇ r´ adce
´ Poznamka: Moˇzne´ pˇr´ıpony: .cc, .cpp, .C, .c++, .cxx ´ r C++ ICP — Seminaˇ
9/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ Pˇr´ıklad: cˇ ten´ı a tisk C++ ˇretezce
´ r C++ ICP — Seminaˇ
10/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ˇ Pˇr´ıklad: cˇ ten´ı a tisk C ˇretezce v C++ (NEVHODNE) // hroz´ ı chyba typu "buffer overflow" [NEPOUˇ Z´ IVAT]
#include #include <string>
#include #include <string>
// std::string
int main() { using namespace std; // nemus´ ıme ps´ at std:: 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ˇ
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; } 11/245
´ r C++ ICP — Seminaˇ
12/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: cˇ etnost slov
#include #include <string> #include <map>
´ r C++ ICP — Seminaˇ
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"; } 13/245
´ Uvod Jazyk Knihovny C++11
// kontejner std::map
typedef std::map<std::string,int> typedef map_t::iterator
int main() { std::string word; std::map<std::string,int> m; // asociativn´ ı pole while( std::cin >> word ) // ˇ cte slova m[word]++; for(auto x: m) // iterace a tisk std::cout << x.first <<"\t"<< x.second <<"\n"; }
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: ˇrazen´ı cˇ ´ısel
14/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: ˇrazen´ı cˇ ´ısel (nemodern´ı, C++98)
// // // //
#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 }
cout vector sort, copy ostream_iterator
int main() { using namespace std; vector v{4, 2, 5, 1, 3}; // inicializace sort(begin(v), end(v)); // ˇ razen´ ı ostream_iterator o(cout,"\n"); // iter´ ator copy(begin(v), end(v), o); // tisk }
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: cˇ etnost slov (nemodern´ı, C++98)
// g++ -std=c++11 (nebo c++0x) #include #include <string> #include <map> // kontejner std::map
// g++ -std=c++11 #include #include #include #include
´ Uvod Jazyk Knihovny C++11
15/245
´ r C++ ICP — Seminaˇ
16/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: ˇrazen´ı cˇ ´ısel — varianta 2 #include #include #include #include
// // // //
// g++ -std=c++11 #include #include #include
// cout // vector // sort, copy, for_each
int main() { using namespace std; vector v{ 4, 2, 5, 1, 3 }; // inicializace sort(begin(v), end(v), [](int x, int y){return x>y;} ); // ˇ razen´ ı int a = 10; // lok´ aln´ ı objekt for_each(begin(v), end(v), [&a](int &x){ x += a++; }); // "closure" for(auto x: v) // tisk cout << x << endl; }
int main() { using namespace std; vector v; int i; while ( cin >> i ) // ˇ cten´ ı ˇ c´ ısel ze vstupu v.push_back(i); // vektor se zvˇ etˇ suje sort(v.begin(), v.end()); // ˇ razen´ ı ostream_iterator o(cout, "\n"); copy(v.begin(), v.end(), o); // tisk } 17/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: lambda funkce
vector sort, copy cout ostream_iterator
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
18/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Rozd´ıly mezi C a C++ ... V´ycˇ tov´y typ nen´ı ekvivalentn´ı typu int enum e { A }; sizeof(A) == sizeof(int) // C sizeof(A) == sizeof(e) // C++ != sizeof(int)
´ ı z jazyka C C++ vychaz´ ´ 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:
´ 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++ }
´ jsou typu char Znakove´ literaly sizeof(’a’) == sizeof(int) // C sizeof(’a’) == sizeof(char) // C++
´ r C++ ICP — Seminaˇ
19/245
´ r C++ ICP — Seminaˇ
20/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Rozˇs´ıˇren´ı C++11 proti C99
´ ´ jmeno tˇr´ıdy a v´ycˇ tu je jmeno typu ukazatele na cˇ leny tˇr´ıd
anonymn´ı unie (jsou v C11) ˇ zovan´ ´ ı funkc´ı a operator ´ u˚ pˇreteˇ
v inicializaci statick´ych objektu˚ je dovolen obecn´y v´yraz genericke´ datove´ typy – sˇ ablony (template, typename)
´ operatory new, delete, new[] a delete[] tˇr´ıdy (class), abstraktn´ı tˇr´ıdy
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)
automaticka´ inicializace (konstruktory, destruktory) zapouzdˇren´ı (private, public, protected) ˇ cnost, nasobn ´ ˇ cnost dediˇ a´ dediˇ ´ polymorfismus (virtualn´ı funkce) uˇzivatelem definovane´ konverze
´ r C++ ICP — Seminaˇ
kl´ıcˇ ove´ slovo mutable
21/245
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
22/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı Novinky v C++11 – pokraˇcovan´
Novinky v C++11
´ silneˇ typovane´ v´ycˇ ty Nove,
R-hodnotove´ reference, ”move” konstruktory
´ v C++98) template> (byl problem ´ explicit pro konverzn´ı operatory
constexpr ˇ ve specifikaci dat ”POD = Plain Old Data” Zmeny
alias sˇ ablony (using) ˇ ˇ ym poˇctem parametru˚ (”variadic Sablony s promenn´ templates”) ˇ ´ Nove´ rˇetezcov e´ literaly
extern template Inicializaˇcn´ı seznamy (initializer_list) ´ Sjednocen´y zapis inicializace (int a{5};) Inference typu˚ (auto, decltype)
´ (10kg, 12345_bignum) Uˇzivatelem definovane´ literaly ´ Podpora vlaken (thread_local, ...)
”range for”– cyklus pˇres rozsah kontejneru Lambda funkce a v´yrazy
default a delete konstruktory atd.
Alternativn´ı syntaxe funkc´ı []f(int x)->int{return x;} ´ ı identifikatory ´ Specialn´ override, final
long long static_assert
nullptr ´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı Rozˇs´ıˇren´ı C++11 proti C99 – pokraˇcovan´
typ reference
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
Moˇznost implementovat ”garbage collector”, ... 23/245
´ r C++ ICP — Seminaˇ
24/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Novinky v C++14
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
C++
ˇ a zruˇsen´ı ruzn´ Male´ zmeny ˚ ych omezen´ı: ´ Poznamky
auto f() { .... return x; } auto parametry lambda funkc´ı ˇ ych sˇ ablony promenn´
/* text pozn´ amky */ // text pozn´ amky plat´ ı aˇ z do konce ˇ r´ adku
inicializace { .field=value, .... } ´ ı literaly ´ binarn´ 0b0110
´ 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++.
ˇ ´ oddelovaˇ ce v numerick´ych literalech 10’000’000 vylepˇsen´ı a rozˇs´ırˇen´ı std knihovny ...
´ r C++ ICP — Seminaˇ
25/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
26/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Kl´ıcˇ ova´ slova C++ asm auto bool break case catch char class const const_cast constexpr continue decltype default delete do double ´ r C++ ICP — Seminaˇ
dynamic_cast else enum explicit extern false float for friend goto if inline int long mutable namespace
new noexcept nullptr operator private protected public register reinterpret_cast return short signed sizeof static static_assert static_cast struct
switch template this throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while
Alternativn´ı reprezentace <% { and %> } bitand <: [ compl :> ] not_eq %: # or_eq %:%: ## xor_eq
&& & ~ != |= ^=
and_eq bitor not or xor
&= | ! || ^
´ Poznamka: Digraphs (<:) ´ Poznamka: Trigraphs (napˇr. ??/)
(bude zruˇseno v C++17)
// Provede se n´ asleduj´ ıc´ ı pˇ r´ ıkaz??/ i++;
27/245
´ r C++ ICP — Seminaˇ
28/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Literaly
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Typova´ kontrola ˇ s´ı neˇz v C: v C++ je silnejˇ
ˇ zn´ych cˇ ´ıseln´ych literal ´ u˚ je stejna´ jako v C. Syntaxe beˇ
Deklarace:
´ (operator "") C++11: uˇzivatelem definovane´ literaly
void (*funptr)();
Pˇr´ıklad: BigNumber operator "" _big(const char * literal_string); BigNumber some_variable = 12345_big; ´ jsou typu: Znakove´ literaly char v C++ int
v C, v C++ pouze v´ıceznakove´ (mbc)
29/245
´ Uvod Jazyk Knihovny C++11
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ˇ tove´ typy: ´ 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´
´ Poznamka: V C++ existuj´ı 3 ruzn ˚ e´ znakove´ typy: char, unsigned char a signed char ´ r C++ ICP — Seminaˇ
je ukazatel na fci vracej´ıc´ı void v C, ukazatel na fci vracej´ıc´ı void bez parametru˚ v C++
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Poznamky
30/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Typ reference Definice: T & x = Lhodnota_typu_T;
ˇ e´ cyklu ve for Rozsah deklarace promenn
Bl´ızke´ ukazatelum ˚ (ale neexistuje obdoba NULL) ´ an´ ´ ı parametru˚ odkazem Pouˇzitelne´ pro pˇredav Nelze vytvoˇrit:
for(int i=1; i<10; i++) { /* zde plat´ ı i */ } Je chybou, kdyˇz je pˇr´ıkazem skoku pˇreskoˇcena inicializace ˇ e´ promenn
referenci na referenci (napˇr. T & & r), ´ je dovoleno, ale jen nepˇr´ımo Pozor: v sˇ ablonach referenci na bitova´ pole, ukazatele na reference, pole referenc´ı.
Pozor na setjmp a longjmp
V´yhodou referenc´ı je jednoduchost pouˇzit´ı (na rozd´ıl od *ptr)
´ r C++ ICP — Seminaˇ
31/245
´ r C++ ICP — Seminaˇ
32/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Reference — chybna´ nebo netypicka´ pouˇzit´ı
Typ reference – pˇr´ıklady double x = 1.23456; double & xref = x; // Typick´ e pouˇ zit´ ı
const int & i = 7; // Vytvoˇ r´ ı pomocnou promˇ ennou int & i = 7; // CHYBA! nelze pro nekonst. referenci
double & yref; extern int & zref;
float f = 3.14; const int & ir = f; // pomocn´ a_promˇ enn´ a = 3 ir = 5; // CHYBA! konstantu nelze zmˇ enit
// CHYBA! chyb´ ı inicializace // extern m˚ uˇ ze b´ yt bez inicializace
// Pˇ red´ an´ ı parametru odkazem: void Transpose(Matrix & m);
´ Poznamka: Proˇc nelze pouˇz´ıt R-hodnotu s nekonstantn´ı referenc´ı: void incr( int& refint ) { refint++; } void g() { // pozor - toto nen´ ı C++ double d = 1; incr(d); // z´ aludn´ a chyba: nezmˇ en´ ı d ! }
// Vracen´ ı reference: int & f(param); // Pozor na to _co_ se vrac´ ı! f(p) = 1;
// Vol´ an´ ı funkce
´ r C++ ICP — Seminaˇ
33/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
R-hodnotove´ reference (R-value references)
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Booleovske´ literaly: false a true Implicitn´ı konverze bool ---> int true ---> 1 false ---> 0
v´ yraz nemus´ı b´yt L-hodnota (Definice pojmu L-hodnota: &(v´ yraz) funguje.) ´ ı) Pouˇzitelne´ pro optimalizaci (omezen´ı kop´ırovan´ viz napˇr´ıklad ”move” konstruktory ´ em ´ pouˇzit´ı (dedukce typu) Perfect forwarding pˇri spravn
Konverze cˇ ´ısel, v´ycˇ tu˚ a ukazatelu˚ na bool 0 ---> false jinak ---> true V´ysledek relaˇcn´ı operace je typu bool
template void f( T && x ); // R-value OR L-value reference
Pˇr´ıklad:
// univerz´ aln´ ı reference (podle y)
Pojmy: lvalue, xvalue, prvalue; glvalue, rvalue ´ r C++ ICP — Seminaˇ
34/245
Typ bool
Definice: T && x = v´ yraz;
auto && x = y;
´ r C++ ICP — Seminaˇ
35/245
bool test = false; test = (a > b); // bool test = 5; // int ---> bool ´ r C++ ICP — Seminaˇ
36/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ u˚ C++ (podle priority; neupln ´ Pˇrehled operator ´ e) ´ operatory ( ) [ ] -> :: . ! ~ + - ++ -- & * (Typ) sizeof new delete .* ->* * / % + << >> < <= > >= == != & ^ | && || ?: = *= /= %= += -= &= ^= |= <<= >>= , ´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
asociativita → ← → → → → → → → → → → → ← ← →
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operatory C++ ´ operator :: .* ->* new delete static_cast reinterpret_cast const_cast dynamic_cast alignof noexcept 37/245
popis ´ kvalifikator dereference ukazatele na cˇ len tˇr´ıdy pˇres objekt (o.*mptr) dereference ukazatele na cˇ len tˇr´ıdy pˇres ukazatel na objekt (ptr->*mptr) dynamicke´ vytvoˇren´ı objektu zruˇsen´ı objektu ´ ´ ı C++ operatory pˇretypovan´
C++11 C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operatory — pˇr´ıklady
38/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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
// 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ˇ
´ Uvod Jazyk Knihovny C++11
39/245
´ r C++ ICP — Seminaˇ
40/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Standardn´ı konverze v C++ I
2
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Standardn´ı konverze v C++ II
´ pˇri Implicitn´ı konverze prob´ıhaj´ı automaticky (jsou-li nutne) ´ ı binarn´ ´ ıch operac´ı: vyhodnocovan´ 1
´ Uvod Jazyk Knihovny C++11
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.
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.
ˇ ´ Je-li nekter´ y operand long double, je druh´y konvertovan na long double
´ r C++ ICP — Seminaˇ
41/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Konverze — pˇr´ıklady
42/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Explicitn´ı konverze ´ ı programator ´ Explicitn´ı konverze uvad´ do textu programu ˇ (a pˇreb´ıra´ za neˇ veˇskerou odpovednost):
´ Poznamka: ´ an´ ´ ı cˇ ´ısla int s cˇ ´ıslem unsigned muˇ Pˇri porovnav ˚ ze doj´ıt k (pro ˇ ´ ´ nekoho neoˇcekavan´ym) problemum: ˚
(typ) v´ yraz (C kompatibilita, nepouˇ z´ ıvat) typ(v´ yraz) static_cast(v´ yraz)
int i = -1; unsigned u = 1234U; if(i
´ r C++ ICP — Seminaˇ
Pˇr´ıklady: // sledujte varov´ an´ ı pˇ rekladaˇ ce // nevytiskne nic!
´ ı Explicitn´ı pˇretypovan´
double(int1)/int2 complex(3.14) int(’c’) static_cast(ptr) reinterpret_cast(ptr) 43/245
´ r C++ ICP — Seminaˇ
44/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
Preprocesor
extern "C"
´ ı, Je stejn´y jako v ISO C, je vhodne´ minimalizovat jeho pouˇz´ıvan´ ´ protoˇze mame lepˇs´ı prostˇredky:
Moˇznost pouˇzit´ı funkc´ı z knihoven jazyka C, pˇr´ıpadneˇ jin´ych jazyku: ˚
lze nahradit za:
#define K1 10 extern "C" int f(int);
const int K1 = 10;
extern "C" { int g(int); int h(int); }
#define f(x)
ˇ sinou nahradit za: lze vetˇ
pˇr´ıpadneˇ lze pouˇz´ıt genericke´ funkce: template inline T f(T x) { return v´ yraz_x; }
´ r C++ ICP — Seminaˇ
45/245
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Zakladn´ ı principy OO pˇr´ıstupu
46/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
V´yvoj programu˚ ´ ´ ı – udrˇ anal´yza – navrh – implementace – testovan´ ´ zba
Tradiˇcn´ı pˇr´ıstup program = data + algoritmy(podprogramy) ´ ı pˇr´ıstup Modularn´
Objektoveˇ orientovana´ anal´yza (OOA) ´ ı poˇzadavku˚ z hlediska tˇr´ıd a objektu˚ zkouman´
program = moduly modul = data + algoritmy(podprogramy) Objektoveˇ orientovan´y pˇr´ıstup
´ Objektoveˇ orientovan´y navrh (OOD) dekompozice ´ popis systemu a jeho charakteristik notace (grafy)
program = objekty + komunikace
´ ı (OOP) Objektoveˇ orientovane´ programovan´
ˇ 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ˇ
(v´ yraz_x)
inline int f(int x) { return v´ yraz_x; }
´ Poznamka: Prostory jmen
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
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
47/245
´ r C++ ICP — Seminaˇ
48/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Objektov´y model
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Notace
Hlavn´ı principy Abstrakce Zapouzdˇren´ı Modularita (fyz.) Hierarchie
Pouˇzit´ı grafu: ˚ diagramy tˇr´ıd diagramy objektu˚
Vedlejˇs´ı principy ´ ı typovan´ paralelismus persistence
diagramy komunikace objektu˚ ´ Poznamka: UML
´ Poznamky: tyto principy nejsou nove´ ˇ cnost = hierarchie abstrakc´ı dediˇ
´ r C++ ICP — Seminaˇ
49/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Tˇr´ıdy
50/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Tˇr´ıdy a objekty — pˇr´ıklad tˇ r´ ıda = data + funkce + zapouzdˇ ren´ ı
Pˇr´ıklad: Pouˇzit´ı tˇr´ıdy T
´ 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´ ı
T x; T &refx = x; T *ptrx = &x; T xarr[20]; T f(); T &&rref = f();
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ˇ
// // // // // //
objekt tˇ r´ ıdy T reference na objekt T ukazatel na objekt T pole objekt˚ u tˇ r´ ıdy T funkce vracej´ ıc´ ı T C++11: R-value reference
´ Poznamky: ´ tˇr´ıdy je stejn´y jako u struktur Pˇr´ıstup ke sloˇzkam ”One definition rule” 51/245
´ r C++ ICP — Seminaˇ
52/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Datove´ cˇ leny a vnoˇrene´ objekty
´ Uvod Jazyk Knihovny C++11
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
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)
int i; // je v kaˇ zd´ em objektu int j = 5; // C++11: inicializace enum XE { A=10, B, C, D, E, F } e; string s; // v kaˇ zd´ em objektu double data[3]; // v kaˇ zd´ em objektu
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ˇ
}; int X::count = 0; // Pozor! je nutn´ a definice v modulu
53/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ 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; };
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´ı:
´ r C++ ICP — Seminaˇ
54/245
Kontrola pˇr´ıstupu ke cˇ lenum ˚ tˇr´ıd — pˇr´ıklad
Specifikace pˇr´ıstupu
pro definici class struct union
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Kontrola pˇr´ıstupu ke cˇ lenum ˚ tˇr´ıd
public private protected
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
implicitneˇ plat´ı private public public
lze pˇredefinovat? ano ano ne
55/245
´ r C++ ICP — Seminaˇ
class => implicitnˇ e private public protected public
56/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Friend funkce a tˇr´ıdy
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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; // } };
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ˇ
int f(X *ptr) { ptr->data = 1; } 57/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
priv´ atn´ ı data friend tˇ r´ ıda Y deklarace friend funkce definice tˇ r´ ıdy pˇ r´ ıstup je moˇ zn´ y
// definice funkce // pˇ r´ ıstup je moˇ zn´ y
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Metody
nekompletn´ ı deklarace tˇ r´ ıdy Y
58/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Inline metody ´ ı) optimalizace (ale je moˇzne´ i volan´ ´ e´ funkce (jinak ”code bloat”) vhodne´ pro kratk
Kategorie metod
´ mus´ı b´yt definovana stejneˇ pro kaˇzd´y modul metoda definovana´ uvnitˇr tˇr´ıdy je automaticky inline:
Konstruktory (vznik objektu) ´ Destruktor (zanik objektu)
class X { char *i; public: char *f() const { // implicitnˇ e inline return i; } }; ´ s explicitn´ım uveden´ım kl´ıcˇ oveho slova inline:
Staticke´ metody ˇ zne´ metody (ne staticke) ´ Beˇ ´ ı metody (pro polymorfismus) Virtualn´ ´ Operatory (ruzn ˚ e´ operace: + - * /) ´ ı objektu na jin´y typ) Konverze (pˇretypovan´
inline char *X::f() const { return i; } ´ r C++ ICP — Seminaˇ
59/245
´ r C++ ICP — Seminaˇ
60/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
// 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() const { return n; } void Print() const; };
Implicitn´ı parametr nestatick´ych metod 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. ´ (template) se ve specialn´ ´ ıch pˇr´ıpadech mus´ı V sˇ ablonach pouˇz´ıvat this->ˇ clen this lze pouˇz´ıt pouze uvnitˇr nestaticke´ metody (napˇr´ıklad ´ ı odkazu na objekt do jine´ funkce). pro pˇredan´
void Int_1_10::SetValue(int x) { // definice metody if(x<1 || x>10) error("Range error"); n = x; } 61/245
´ Uvod Jazyk Knihovny C++11
62/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Staticke´ metody
class T { public: void f() { std::cout << "T\n"; } void f() const { std::cout << "const T\n"; } T clone() const { return *this; } };
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 dane´ tˇr´ıdy se mus´ı kvalifikovat T::staticka_metoda(parametry) ´ y objekt lze je volat i kdyˇz neexistuje zˇ adn´
// 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ˇ
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad pouˇzit´ı this
T o1; const T o2 = T();
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Kl´ıcˇ ove´ slovo this
Jednoduch´y pˇr´ıklad: tˇr´ıda interval
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
vhodne´ napˇr. po pomocne´ funkce pro tˇr´ıdu
63/245
´ r C++ ICP — Seminaˇ
64/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Staticke´ metody — pˇr´ıklad
´ Uvod Jazyk Knihovny C++11
Vnoˇrene´ typy
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(); }
// // // //
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)
nepotˇ rebuje objekt definice objektu tˇ r´ ıdy objekt pˇ red´ an explicitnˇ e obyˇ cejn´ a metoda
´ r C++ ICP — Seminaˇ
65/245
´ Uvod Jazyk Knihovny C++11
int main() { A::B obj; A::MujTyp i = 5; obj.MetodaB(i); } ´ r C++ ICP — Seminaˇ
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
66/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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).
// vnoˇ ren´ y typ // definice vnoˇ ren´ e tˇ r´ ıdy // deklarace metody
Alokace objektu˚ new T 1 ˇ ’ pro objekt alokuje pamet
// deklarace vnoˇ ren´ e tˇ r´ ıdy C // definice C mimo tˇ r´ ıdu A i) { } // definice metody
pouˇzije T::operator new(), pokud existuje jinak pouˇzije ::operator new()
// B je public
2
operator new pˇri chybeˇ vyvola´ v´yjimku bad_alloc ˇ sne´ alokaci je vyvolan ´ konstruktor po usp ´ eˇ
Pˇr´ıklad: (C++11) auto ptr = new vector{1,2,3}; 67/245
´ r C++ ICP — Seminaˇ
68/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator delete Alokace pol´ı new T[velikost] 1 ˇ ’ pro pole alokuje pamet
ˇ ı pameti ˇ Uvolnen´ delete ptr delete[] ptr 1 ´ ´ poˇrad´ı neˇz pˇri new vola´ destruktory v obracen em 2 ˇ ’ volan´ ´ ım T::operator delete() nebo uvoln´ı pamet ::operator delete() (pˇr´ıpadneˇ varianta s delete[] 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´ıklady: delete ukazatel; // ruˇ s´ ı objekt alokovan´ y new T delete [] ptr; // ruˇ sı ´ pole alokovan´ e new T[n]
Pˇr´ıklad: T *pt = new T[10]; // pole 10 objekt˚ u ´ r C++ ICP — Seminaˇ
69/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı alokace pameti ˇ Specialn´
70/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı alokace pameti ˇ – nothrow 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´ (”Placement new”).
´ ´ ı variantu operatoru ´ Identifikator nothrow pro specialn´ ˇ hodnotu nullptr new(nothrow) vracej´ıc´ı pˇri nedostatku pameti ´ ı v´yjimky bad_alloc. (0 v C++98) m´ısto vyvolan´
new mus´ı m´ıt prvn´ı parametr typu size_t delete mus´ı m´ıt prvn´ı parametr typu void*
´ ´ Pouˇzitelne´ pro systemy, kde je reˇzie v´yjimek neˇzadouc´ ı. Pˇr´ıklad: Pouˇzit´ı nothrow
´ ı operatoru ´ Pˇr´ıklady volan´ new new T vol´ a operator new(adr) T operator new T[5] operator new(22) T[5] operator
T *p = new(nothrow) T; if( p==nullptr ) errorexit("M´ alo pamˇ eti"); // ... delete p;
new(sizeof(T)) new(sizeof(T),adr) new[](sizeof(T)*5 + x) new[](sizeof(T)*5 + y, 22)
( x a y jsou implementac´ı definovane´ hodnoty ) ´ r C++ ICP — Seminaˇ
71/245
´ r C++ ICP — Seminaˇ
72/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
´ ı alokace objektu˚ tˇr´ıdy — pˇr´ıklad Specialn´
Definice new a delete pro tˇr´ıdu
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 ::new //=== ZDE m˚ uˇ zeme prov´ est potˇ rebn´ e operace ... return static_cast(ptr); } void T::operator delete (void* ptr) { //=== ZDE m˚ uˇ zeme prov´ est potˇ rebn´ e operace, // napˇ r. vynulov´ an´ ı z bezpeˇ cnostn´ ıch d˚ uvod˚ u delete[] static_cast(ptr); // ::delete }
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 ´ ı) operatory. ´ standardn´ı (globaln´
´ r C++ ICP — Seminaˇ
73/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Konstruktory
74/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Konstruktory – pˇr´ıklad class X { int i; public: X(): i{} {} // implicitn´ ı konstruktor X(int x): i{x} {}; // konstruktor s parametrem X(T x): X{convtoint(x)} {}; // delegace X(const X&) =default; // kop´ ırovac´ ı konstruktor X(X&&) =default; // "move"~ konstruktor };
´ ı 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 i pro const a volatile objekty ´ ´ ren´ı objektu˚ delete nebo private: – lze zakazat vytvaˇ nelze z´ıskat adresu konstruktoru C++11: delegating constructor – vola´ jin´y konstruktor
X X X X X X
´ Poznamka: Implicitn´ı konstruktor je kaˇzd´y konstruktor, kter´y lze zavolat bez parametru˚ (a muˇ ˚ ze b´yt pouze jeden pro jednu tˇr´ıdu). ´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
75/245
o; // vol´ a o2{55}; o3 = 55; o4{o2}; *px = new X; *px2 = new X{666};
´ r C++ ICP — Seminaˇ
se // // // // //
X::X() X::X(int) X::X(int) a X::X(X&&) X::X(const X&) X::X() X::X(int) 76/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ren´ı metod pˇrekladaˇcem 1 Implicitn´ı vytvaˇ
C++11: Specifikace = default vytoˇr´ı implicitn´ı verzi. ´ ze implicitn´ı vytvoˇren´ı. Specifikace = delete zakaˇ
implicitn´ı konstruktor X::X() kop´ırovac´ı konstruktor X::X(const X&) ”move” konstruktor X::X(X&&) ´ operator pˇriˇrazen´ı X &X::operator = (const X&) ´ ”move” operator pˇriˇrazen´ı X &X::operator = (X&&)
Pˇr´ıklad: struct X { X() = default; X(int);
destruktor X::~X() ´ jin´y konstruktor, pak Omezen´ı: Napˇr. pokud jiˇz je definovan k vytvoˇren´ı X::X() nedojde. Pˇrekladaˇcem vytvoˇrene´ metody jsou vˇzdy public: inline ˇ Pokud nekter´ y cˇ len tˇr´ıdy nelze implicitneˇ odpov´ıdaj´ıc´ım zpusobem zkonstruovat, je program chybneˇ vytvoˇren. ˚ ˇ Nekdy (typicky u tˇr´ıd obsahuj´ıc´ıch ukazatel) implicitn´ı verze operac´ı nevyhovuj´ı a mus´ıme je definovat.
// Bez tohoto se nevytvoˇ r´ ı, // protoˇ ze je tu jin´ y konstruktor.
// Z´ akaz kop´ ırovac´ ıho konstruktoru a pˇ riˇ razen´ ı: X(const X&) = delete; X& operator=(const X&) = delete; .... }; 77/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ren´ı metod pˇrekladaˇcem 2 Implicitn´ı vytvaˇ
´ explicitne, ˇ pˇrekladaˇc muˇ Pokud nen´ı definovan ˚ ze vytvoˇrit:
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Kop´ırovac´ı konstruktor (Copy constructor)
78/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Kop´ırovac´ı konstruktor – pˇr´ıklad
ma´ jeden parametr typu const X& (nebo nevhodneˇ X&), ´ pˇri vzniku objektu kop´ırovan´ ´ ım: je volan
´ Ukazka jake´ konstruktory se pouˇzij´ı v ruzn´ ˚ ych situac´ıch:
definice s inicializac´ı jin´ym objektem, ´ an´ ´ ı parametru hodnotou, pˇredav vracen´ı hodnoty z funkce, ´ ı a zpracovan´ ´ ı v´yjimek, vyvolan´
X f(X p) { X a; X b{a}; X b2(a); X c = a; return a; f(a); throw a; }
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:
// // // // // // // //
* pˇ red´ an´ ı parametru hodnotou implicitn´ ı konstruktor kop´ ırovac´ ı konstruktor kop´ ırovac´ ı konstruktor kop´ ırovac´ ı konstruktor kop´ ırovac´ ı konstruktor * kop´ ırovac´ ı konstruktor kop´ ırovac´ ı konstruktor
ˇ ´ Nezameˇ novat s operatorem pˇriˇrazen´ı! Moˇznost optimalizace (copy elision) ´ r C++ ICP — Seminaˇ
79/245
´ r C++ ICP — Seminaˇ
80/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ ”Stehovac´ ı” konstruktor (Move constructor)
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:
deklarace s inicializac´ı a pouˇzit´ım std::move() vracen´ı hodnoty z funkce s pouˇzit´ım std::move()
class X { complex c1; complex c2; public: X() {} // implicitn´ ı konstruktory c1 a c2 X(double a) : c2{a}, c1{5} {} // poˇ rad´ ı c1 c2 };
Pokud je vytvoˇren pˇrekladaˇcem, pouˇzije ”move” konstruktory sloˇzek X::X(X && o): s1{std::move(o.s1)} {} ´ Poznamky: ˇ ´ Nezameˇ novat s ”move” operatorem pˇriˇrazen´ı! ˇ ´ ı – viz Umoˇznuje explicitneˇ omezit zbyteˇcne´ kop´ırovan´ napˇr. vˇsechny standardn´ı kontejnery.
´ ı konstruktoru˚ c1 a c2 ! ´ Poznamka: Pozor na poˇrad´ı volan´ Automaticky vytvoˇren´y (nekop´ırovac´ı) konstruktor inicializuje vnoˇrene´ objekty implicitn´ımi konstruktory. 81/245
´ Uvod Jazyk Knihovny C++11
82/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Inicializace doˇcasn´ych objektu˚
´ v rostouc´ım poˇrad´ı Konstruktory pro elementy pole jsou volany indexu˚
´ ret doˇcasne´ objekty: Pˇrekladaˇc muˇ ˚ ze vytvaˇ Implicitneˇ (ve v´yrazech, inicializaci referenc´ı, ...)
Pˇr´ıklad:
´ Explicitneˇ zapisem: // X::X() // X::X() // X::X(const X&)
X(22); // pouˇ zije se X::X(int) ^^^^ funguje jako konverze int ---> X ´ Poznamka: Doˇcasne´ objekty pˇrekladaˇc automaticky ruˇs´ı — viz destruktory.
´ Poznamka: Moˇzne´ optimalizace kop´ırovac´ıch konstruktoru˚ (elision)
´ r C++ ICP — Seminaˇ
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Inicializace pole objektu˚
X pole[10]; X *ptr = new X[10]; X p[10] = { X(1), X(2), };
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Inicializace vnoˇren´ych objektu˚
ma´ jeden parametr typu X&& ´ pˇri vzniku objektu z R-hodnoty: je volan
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
83/245
´ r C++ ICP — Seminaˇ
84/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
´ ı Destruktor – pokraˇcovan´
Destruktor ´ ´ 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 vlakna, konec programu, ...)
´ Poznamky: Konˇc´ı-li rozsah platnosti ukazatele na objekt, c´ılov´y objekt ´ se neruˇs´ı (zruˇsen´ı provede operator delete). ´ ıch pˇr´ıpadech volat explicitne: ˇ Destruktor lze ve specialn´
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´
X *p = new X; p->~X(); // destrukce bez uvolnˇ en´ ı pamˇ eti // potom uˇ z nelze pouˇ z´ ıt delete p; ::operator delete(static_cast(p));
´ 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
´ ı. Destruktory polymorfn´ıch tˇr´ıd maj´ı b´yt virtualn´ Destruktor nesm´ı vyhodit v´yjimku — vˇsechny uvnitˇr vznikle´ v´yjimky mus´ı obslouˇzit.
u pol´ı se volaj´ı v klesaj´ıc´ım poˇrad´ı indexu˚ ´ r C++ ICP — Seminaˇ
85/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Ruˇsen´ı doˇcasn´ych objektu˚
86/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Konverze
´ ´ Doˇcasne´ objekty jsou automaticky ruˇseny vˇzdy v obracen em poˇrad´ı jejich vzniku: ´ vznikly, na konci v´yrazu ve kterem
ˇ typu v´yrazu na jin´y typ (T1 → T2) Pouˇz´ıvaj´ı se pro zmenu Kategorie konverzn´ıch operac´ı ´ jazyka C++) Standardn´ı konverze (souˇcast Uˇzivatelske´ konverze (definovane´ v programu):
jde-li o inicializaci, potom aˇz po dokonˇcen´ı inicializace, odkazuje-li se na neˇ reference, pak
´ 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 na jednu hodnotu (tj. neprovede se konverze A → B → C, kdyˇz neexistuje pˇr´ımo A → C)
´ ´ ı pˇr´ıpady!), pˇri zaniku reference (Pozor na specialn´ na konci konstruktoru v jehoˇz inicializaˇcn´ı sekci vznikly, na konci funkce v pˇr´ıpadeˇ jejich vzniku v pˇr´ıkazu return
´ ´ ı promennou ˇ Pozor: vracen´ ı reference na lokaln´ je chyba. ´ Poznamka: Podrobnosti viz norma/12.2
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
87/245
´ r C++ ICP — Seminaˇ
88/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı Konverze — pokraˇcovan´
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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 implicitn´ ı }
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 C++11: je moˇzna´ specifikace explicit ´ nemaj´ı navratov´ y typ a jsou bez parametru. ˚ Napˇr: Trida::operator T() { return vyraz_typu_T; } ´ ˇ ı a mohou b´yt virtualn´ ´ ı tyto operatory se ded´
´ r C++ ICP — Seminaˇ
89/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı operator ´ u˚ Pˇreteˇ
90/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı operator ´ u˚ 2 Pˇreteˇ
ˇ zovan´ ´ ı = pˇrisouzen´ı v´ıce v´yznamu˚ jednomu symbolu Pˇreteˇ ˇ ´ ´ implicitne: ˇ Nekter e´ operatory jsou definovany
ˇ ı zapisu ´ C´ıl: zpˇrehlednen´ programu˚ ´ ı podle kontextu Rozliˇsen´ı operac´ı se provad´
pˇriˇrazen´ı (X & operator = (const X&);) ”move” pˇriˇrazen´ı (X & operator = (X&&);) ´ ı adresy objektu (unarn´ ´ ı & ) z´ıskan´
ˇ zovat vˇsechny operatory ´ ˇ Lze pˇreteˇ C++ krome: . .* :: ?: sizeof 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:
ˇ cˇ lenu struktury ( . ) v´yber ˇ cˇ lenu struktury ( -> ) v´yber velikost objektu sizeof ˇ a pouze nekter e´ z nich muˇ ˚ zeme pˇret´ızˇ it.
´ ´ 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´ ´ r C++ ICP — Seminaˇ
91/245
´ r C++ ICP — Seminaˇ
92/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı operator ´ u˚ 3 Pˇreteˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı unarn´ ´ ıch operator ´ u˚ 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@
´ Uvod Jazyk Knihovny C++11
jako metoda (a).operator@ () (a).operator@ (b) (a).operator= (b) (a).operator[](b) (a).operator->() (a).operator@ (0)
´ ıch operator ´ u˚ Moˇzne´ formy deklarace unarn´ nestaticka´ metoda bez parametru˚ funkce (ne metoda) s jedn´ım parametrem
jako funkce operator@ (a) operator@ (a, b)
´ ı operator, ´ Kdyˇz znak @ reprezentuje unarn´ potom: @x a x@ ´ ´ ı metody: muˇ bud’ jako volan´ ˚ ze b´yt oboj´ı interpretovano
operator@ (a, 0)
x.operator @() ´ ´ ´ ı 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´ı ´ ı argumentu˚ pro ˇreˇsen´ı nejednoznaˇcnosti. testovan´ ´ r C++ ICP — Seminaˇ
´ ı funkce: nebo jako volan´ operator @(x) ´ podle formy deklarace operatoru. 93/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı unarn´ ´ ıch operator ´ u˚ 2 Pˇreteˇ
94/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı binarn´ ´ ıch operator ´ u˚ Pˇreteˇ ´ ıch operator ´ u˚ Moˇzne´ formy deklarace binarn´
´ Prefixove´ a postfixove´ operatory ++ -- lze rozliˇsit pomoc´ı ´ ´ dodateˇcneho fiktivn´ıho parametru operatoru:
nestaticka´ metoda s jedn´ım parametrem ˇ funkce (ne metoda) se dvema parametry
class Y { // ... public: Y operator ++() { /* inkrementace ++x */ } Y operator ++(int) { /* inkrementace x++ */ } }; Y x,y; y = ++x; y = x++;
´ r C++ ICP — Seminaˇ
V´yraz: x@y ´ bud’ jako volan´ ´ ı metody: je interpretovan x.operator @(y)
// vol´ a // vol´ a
Y::operator ++() Y::operator ++(int)
´ ı funkce: nebo jako volan´ operator @(x,y)
´ r C++ ICP — Seminaˇ
95/245
´ r C++ ICP — Seminaˇ
96/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı binarn´ ´ ıch operator ´ u˚ — pˇr´ıklad Pˇreteˇ
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´
Complex operator +(Complex c1, Complex c2) { return Complex(c1.re + c2.re, c1.im + c2.im); }
´ Poznamky: pˇri implementaci je tˇreba uvaˇzovat i moˇznost pˇriˇrazen´ı typu a = a; (Napˇr: p[i] = p[j]; pro i==j ) ´ ıme vytvoˇren´ı operatoru ´ specifikac´ı = delete zabran´
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
´ pˇriˇrazovan´ ´ ı objektu˚ specifikac´ı private muˇ ˚ zeme zabranit 97/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ”move” operator pˇriˇrazen´ı
98/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı operatoru ´ Pˇreteˇ pˇriˇrazen´ı — pˇr´ıklad class String { public: // copy-assignment: String & operator = (const String & str) { if(&str!=this) // ... pˇ riˇ razen´ ı dat (delete,new,copy) return *this; } // move-assignment: String & operator = (String && s); String & operator = (const char *cstr) { *this = String(cstr); // pouˇ zije "move"= return *this; } // ... dalˇ s´ ı metody: konstruktory atd. // ... odkaz na priv. data (pro kaˇ zd´ y objekt) };
T& T::operator= (T&&); ´ ”move” operator =, pˇrekladaˇc jej vytvoˇr´ı nen´ı-li definovan ´ jako ”move” pˇriˇrazen´ı po jednotliv´ych sloˇzkach ˇ ı se neded´ ´ ı muˇ ˚ ze b´yt virtualn´ ´ Poznamky: implementuje se obvykle jako operace swap ´ ıme vytvoˇren´ı operatoru ´ specifikac´ı = delete zabran´ ´ pˇriˇrazovan´ ´ ı objektu˚ specifikac´ı private muˇ ˚ zeme zabranit
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı operatoru ´ Pˇreteˇ pˇriˇrazen´ı
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); // pouˇ zit´ ı funkce ˇ reˇ s´ ı probl´ em: 1 + Complex(1,2) };
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
99/245
´ r C++ ICP — Seminaˇ
100/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı operatoru ´ ´ ı funkce Pˇreteˇ volan´
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı operatoru ´ ´ ı pole Pˇreteˇ indexovan´
typ_prvku& T::operator[] (typ_indexu); typ T::operator() (parametry); ´ pouze jako nestaticka´ metoda muˇ ˚ ze b´yt definovan ´ ı operator ´ ´ ı a[b] Binarn´ indexovan´ ´ jako a.operator[](b) je interpretovan ´ ´ ı: v´ıcenasobn e´ indexovan´
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).
´ ´ ı 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
Pouˇzit´ı: funkˇcn´ı objekty v STL std::less()
´ r C++ ICP — Seminaˇ
101/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı pˇr´ıstupoveho ´ ´ Pˇreteˇ operatoru ->
102/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Omezen´ı pro doˇcasne´ objekty Nelze volat metody pro doˇcasne´ objekty vytvoˇrene´ napˇr´ıklad implicitn´ı konverz´ı: class X { int i; public: X(int _i=0) : i(_i) {} X operator + (const X &b) const { return X(i + b.i); } };
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ˇ
int X a a } 103/245
main() { a, b; = 5 + b; = X(5) + b;
´ r C++ ICP — Seminaˇ
// chyba // OK 104/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı funkc´ı Pˇreteˇ
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ zovan´ ´ ı funkc´ı – pˇr´ıklad Pˇreteˇ
´ Moˇznost deklarovat v´ıce funkc´ı se stejn´ym jmenem
void print(double); void print(long);
´ ı rozliˇsuj´ı se podle poˇctu a typu argumentu˚ pˇri volan´ souvislost s typovou kontrolou ´ ı funkc´ı (ADL) pravidla pro vyhledan´
void F() { print(1L); print(1.0); print(1); }
´ 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
ˇ sen´ı nejednoznaˇcnosti: Reˇ ´ ı nebo definice dalˇs´ı funkce void print(int); pˇretypovan´
´ Poznamka: typedef nedefinuje samostatn´y typ
´ r C++ ICP — Seminaˇ
105/245
´ Uvod Jazyk Knihovny C++11
// tiskne long // tiskne double // CHYBA: nejednoznaˇ cnost
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
106/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ an´ ´ ı prostoru˚ jmen Pravidla pro prohledav
Rozliˇsen´ı typu˚
(”Argument Dependent Lookup-ADL = ”Koenig lookup”) ˇ zovan´ ´ ı nelze rozliˇsit nekter ˇ ´ Poznamka: Pˇri pˇreteˇ e´ typy: void f(int); void f(const int);
´ volan´ ´ ı funkce f s pˇr´ıpadn´ymi parametry Pˇri nekvalifikovanem ´ ych funkc´ı takto: se hleda´ 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); nav´ıc se uvaˇzuj´ı i ke globaln´ 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)
// 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
4
´ r C++ ICP — Seminaˇ
107/245
´ ı se chyba. Nenajde-li se odpov´ıdaj´ıc´ı funkce, hlas´
´ r C++ ICP — Seminaˇ
108/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ odpov´ıdaj´ıc´ı funkce Pravidla pro v´yber
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ˇ
Moˇzne´ ˇreˇsen´ı: zruˇsen´ı jedne´ z konverz´ı, pˇr´ıpadneˇ pouˇzit´ı specifikace explicit 109/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Vstup/v´ystupn´ı operace s vyuˇzit´ım streamu˚
110/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Definice a pouˇzit´ı vstup/v´ystupn´ıch operac´ı
ˇ ı pojmu soubor stream (proud) – objekt, zobecnen´
´ Zapis
#include #include
cerr << "x=" << x << ’\n’; ´ je ekvivalentn´ı zapisu
tˇr´ıdy ios, istream, ostream, iostream, ifstream, ofstream, fstream a dalˇs´ı
operator<<(operator<<(operator<<(cerr,"x="),x),’\n’);
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ˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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 ?
´ 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
´ Uvod Jazyk Knihovny C++11
´ pro typ objektu x a tiskne x zpusobem, kter´y je definovan ˚ int x = 123; Complex x(1,2.4)
111/245
´ r C++ ICP — Seminaˇ
tiskne: tiskne:
x=123 x=(1,2.4)
112/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Pˇr´ıkld definice v´ystupn´ıho operatoru
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Pˇr´ıkld definice vstupn´ıho operatoru // vstupn´ ı form´ aty:
Pˇr´ıklad pro jednoduchou tˇr´ıdu Complex
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 {
// 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)
´ ı) (pokraˇcovan´ ´ r C++ ICP — Seminaˇ
113/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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;
114/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Chybove´ pˇr´ıznaky ios::eofbit ios::failbit ios::badbit
// O.K.
pokus o cˇ ten´ı za koncem souboru ´ an´ ´ ı, neoˇcekavan´ ´ chyba formatov y znak, ... ´ zna´ chyba, nelze zotavit vaˇ
Metody: bool good() bool eof() bool fail() bool bad() explicit bool() operator void*() void clear()
} ´ Poznamky: ˇ s´ı, protoˇze je nutne´ oˇsetˇrit vˇsechny varianty Vstup je sloˇzitejˇ ´ z jako if(s.fail()) a podm´ınka neplat´ı, if(s) je toteˇ kdyˇz je nastaven pˇr´ıznak ios::failbit (chybne´ ´ an´ ´ ı vstupu, pokus o cˇ ten´ı za EOF) nebo formatov ´ zneji ˇ poruˇsen). ios::badbit (stream je vaˇ ´ r C++ ICP — Seminaˇ
´ r C++ ICP — Seminaˇ
115/245
´ r C++ ICP — Seminaˇ
´ y chybov´y bit nen´ı nastaven zˇ adn´ nastaven eofbit nastaven alesponˇ jeden z failbit, badbit nastaven badbit C++11: vrac´ı !fail() C++98: vrac´ı null kdyˇz plat´ı fail() nuluje pˇr´ıznaky
116/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Manipulatory flush ws hex dec boolalpha ... Pˇr´ıklad:
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Manipulatory s parametry ´ ´ ˇ’ vyprazdn´ ı vyrovnavac´ ı pamet ˇ pˇreskoˇc´ı oddelovaˇ ce na vstupu ´ pouˇzije sˇ estnactkovou notaci pouˇzije des´ıtkovou soustavu pouˇzije ”true”/”false” ...
setfill(char) setprecision(int) setw(int) Pˇr´ıklad:
´ u˚ pouˇzit´ı manipulator
cout <<setw(4)<<setfill(’#’)<< 33 << "+" << 22; v´ ystup: ##33+22
´ u˚ pouˇzit´ı manipulator
cout << "login: " << flush; cin >> noskipws >> x >> ws >> y; cout << 1234 << hex << 1234 << 4321 << dec << endl;
´ r C++ ICP — Seminaˇ
´ ´ Poznamka: Nastaven´ı manipulatoru setw() plat´ı pouze pro ´ jednu tisknutou poloˇzku, ostatn´ı manipulatory plat´ı aˇz do dalˇs´ı ˇ zmeny 117/245
´ Uvod Jazyk Knihovny C++11
ˇ y znak v´yplnov´ pˇresnost sˇ ´ıˇrka tisku
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ se soubory Prace
118/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ se soubory — pˇr´ıklad Prace
´ s diskov´ymi soubory jsou definovany ´ tˇr´ıdy Pro praci
#include using namespace std;
fstream ifstream
ifstream from("soubor1.txt"); ofstream to("soubor2.txt"); fstream f("soubor3.txt", ios::in | ios::out);
ofstream ´ an´ ´ ı streamu na soubor lze provest ´ pˇri vzniku objektu Navaz ´ ım metody open. nebo volan´
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.fail()) // test chyb error("chyba!"); }
Metodou clear() je moˇzne´ zruˇsit chybov´y stav streamu. ´ Poznamka: Kombinace streamu/C-funkc´ ı (napˇr. printf) a ˚ ´ ´ k problem ´ um vlaken muˇ ˚ ze vest ˚ v poˇrad´ı v´ystupu. ˚ std::ios::sync_with_stdio(false); ´ r C++ ICP — Seminaˇ
// =zrychlen´ ı 119/245
´ r C++ ICP — Seminaˇ
120/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ cnost Dediˇ
´ u vˇsech zded ˇ en´ ˇ ych prvku: Specifikace pˇr´ıstupov´ych prav ˚ Pˇr´ıklad class D : public B1, protected B2, B3 {};
´ Bazov e´ (”Base”) a odvozene´ (”Derived”) tˇr´ıdy
Implicitn´ı je private u class D, a public u struct D ˇ ı atributy pˇr´ıstupu takto: Odvozena´ tˇr´ıda ded´
Pˇr´ıklad class D : public B { // tˇ r´ ıda D dˇ ed´ ı tˇ r´ ıdu B // nov´ e poloˇ zky, nov´ e a modifikovan´ e metody };
ˇ en´ ˇ ı Zpusob ded ˚ public B protected B private B
´ 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, Ze zded ktere´ byly public nebo protected ´ r C++ ICP — Seminaˇ
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı konstruktoru˚ a dediˇ ˇ cnost Poˇrad´ı volan´
122/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı konstruktoru˚ — pˇr´ıklad Poˇrad´ı volan´ V pˇr´ıkladu je hruba´ chyba:
Konstruktor odvozene´ tˇr´ıdy je sloˇzen z: 1 ´ ı (inline rozvoje) konstruktoru bazov ´ volan´ e´ tˇr´ıdy,
class Base { int x; public: Base (int i): x(i) {} };
´ ı 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´
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) };
´ ı parametru˚ vyvolan´ym konstruktorum Pˇredan´ ˚ je moˇzne´ za ´ u˚ konstruktoru (viz dvojteˇckou v seznamu inicializator ´ nasleduj´ ıc´ı pˇr´ıklad). ´ ı jineho ´ ´ Poznamka: C++11 dovoluje explicitn´ı volan´ konstruktoru stejne´ tˇr´ıdy. (delegation) ´ v pˇresneˇ ´ Poznamka: Destruktory jsou vˇzdy volany ´ ´ poˇrad´ı neˇz jim odpov´ıdaj´ıc´ı konstruktory. obracen em ´ r C++ ICP — Seminaˇ
ˇ ´ zded ˇ en´ ˇ ych Zmena pˇr´ıstupov´ych prav cˇ lenu˚ z B v odvozene´ tˇr´ıdeˇ D ˇ eno ˇ public i protected nezmen public a protected bude protected vˇsechny cˇ leny budou private
ˇ pˇr´ıstupova´ prava ´ u jednotliv´ych zded ˇ en´ ˇ ych poloˇzek Lze zmenit pouˇzit´ım using deklarace (viz. prostory jmen) ´ pˇred ded ˇ en´ ˇ ım lze obnovit max. na puvodn´ ı urove nˇ prav ˚ ´ 121/245
´ Uvod Jazyk Knihovny C++11
3
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ en´ ˇ ı private, public, protected Ded
´ ı nov´ych tˇr´ıd z jiˇz existuj´ıc´ıch Odvozovan´ ´ ˇ cnost Jednoducha´ a nasobn a´ dediˇ
2
´ Uvod Jazyk Knihovny C++11
123/245
´ r C++ ICP — Seminaˇ
124/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı konstruktoru˚ – pˇr´ıklad 2 Poˇrad´ı volan´
Metody (public) oznaˇcene´ kl´ıcˇ ov´ym slovem virtual ˇ ı polymorfismus: umoˇznuj´ ´ 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 ´ em ´ pouˇzit´ı spoleˇcneho ´ ´ pˇri spravn rozhran´ı nen´ı tˇreba znat pˇresneˇ tˇr´ıdu objektu (jeˇsteˇ nemus´ı existovat) a pˇresto je pˇri ˇ ˇ ´ ı odpov´ıdaj´ıc´ıch metod – behu programu zajiˇsteno volan´ tzv. pozdn´ı vazba (”late binding”). ´ ı ma´ typicky tvar: Polymorfn´ı volan´ ukazatel->vmetoda(parametry);
125/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı metody 2 Virtualn´
126/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı metody – pˇr´ıklad Virtualn´ class B { public: virtual B* vf1() { void f() { cout << }; class C : public B { public: C* vf1() { cout << void f() { cout << }; class D : public B { public: virtual D* vf1() { void f() { };
´ ı destruktory, ktere´ umoˇznuj´ ˇ ı korektneˇ Lze definovat virtualn´ ruˇsit prvky dynamick´ych 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ˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı metody Virtualn´
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 sloˇ zku x // 3) complex::complex() pro y // z neinicializov´ ano = pozor na nekorektn´ ı k´ od // 4) vol´ an´ ı f() }; ´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
127/245
´ r C++ ICP — Seminaˇ
cout << "B"; return this; } "B"; /* vf1(); this->vf1(); */ }
"C"; return this; } // virtual "C"; }
cout << "D"; return this; } cout << "D"; } 128/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı metody – pˇr´ıklad – pokraˇcovan´ ´ ı Virtualn´
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı metody — implementace 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(); //
´ Uvod Jazyk Knihovny C++11
´ ı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.
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ˇ
129/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
130/245
´ Uvod Jazyk Knihovny C++11
´ Pˇr´ıklad implementace polymorfismu — obrazek
Pˇr´ıklad implementace polymorfismu class B { public: virtual void vf1(); // rozhran´ ı // ... } b;
VMT B b vf1B
class C : public B { // mus´ ı b´ yt public public: virtual void vf1(); // ... } c; B *bp = &c;
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
void vf1() {} VMT C c vf1C
void vf1() {}
// polymorfn´ ı rozhran´ ı: bp->vf1()
bp ´ r C++ ICP — Seminaˇ
131/245
´ r C++ ICP — Seminaˇ
132/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ r k polymorfismu Komentaˇ
´ r C++ ICP — Seminaˇ
´ 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). ´ Poznamka: Dynamick´y vs statick´y polymorfismus ´ Poznamka: Moˇznost optimalizace (inline rozvoj, ...)
133/245
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı virtualn´ ´ ıch metod tˇr´ıdy v konstruktoru Volan´
134/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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 }
´ en´ ˇ ı konstruktoru˚ (a destruktoru) Pˇri provad ˚ se mechanismus ´ ı virtualn´ ´ ıch metod neuplatnuje ˇ 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´ muˇ ˚ ze pracovat s jeˇsteˇ neinicializovan´ymi sloˇzkami objektu. ´ ame ´ ´ ı — viz ´ Poznamka: Pˇredpoklad polymorfn´ı volan´ ´ nasleduj´ ıc´ı pˇr´ıklad. ´ ´ Poznamka: Podobneˇ se chova´ typeid — viz dale.
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ r k polymorfismu — pokraˇcovan´ ´ ı 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.
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
135/245
´ r C++ ICP — Seminaˇ
’A’ ; }
’B’ << i << ’ ’ ; }
AB9 a nikoli B?B9 B9 136/245
´ Uvod Jazyk Knihovny C++11
ˇ eˇ virtualn´ ´ ı metody Cist
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ eˇ jednou cˇ isteˇ virtualn´ ´ ı metodou = tˇr´ıdy s minimaln ´ ˇ en´ ˇ ı pouˇzitelne´ pouze jako bazov e´ 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 B { virtual void pvf(int) = 0; };
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´ ı)
´ 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ˇ
137/245
138/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Specifikace override a final [C++11] ´ ı identifikatory ´ specialn´ (ne kl´ıcˇ ova´ slova)
public shape { // kruˇ znice
override zajiˇst’uje kontrolu, zda opravdu jde o ´ ı virt. metody (mus´ı existovat v bazov ´ ˇ pˇredefinovan´ e´ tˇr´ıde). Chyba nastane napˇr´ıklad kdyˇz dojde k pˇret´ızˇ en´ı (jine´ parametry). ´ ı virt. metody v odvozen´ych final zakazuje pˇredefinovan´ ´ nebo zakazuje ded ˇ en´ ˇ ı z dane´ tˇr´ıdy – viz pˇr´ıklad: tˇr´ıdach
rotate(int) {} // definice move(int,int); draw();
class D final : public B { void sone_func() override; // Chyba: pˇ reklep void vf(int) override; // OK: pˇ redef. virt. B::vf(int) virtual void h(char *) final; };
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ˇ
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Abstraktn´ı tˇr´ıdy – pˇr´ıklad class Circle : int radius; public: virtual void virtual void virtual void //... };
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Abstraktn´ı tˇr´ıdy
´ ı metoda nemus´ı b´yt definovana. ´ Virtualn´ Potom mus´ı b´yt ´ ´ ı metoda (”pure virtual deklarovana jako tzv. cˇ isteˇ virtualn´ function”):
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
139/245
´ r C++ ICP — Seminaˇ
140/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator typeid
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator typeid — pˇr´ıklad
class X { // polymorfn´ ı tˇ r´ ıda // ... virtual void f(); // ... };
typeid ( v´ yraz ) typeid ( typ ) ´ ˇ Operator z´ıska´ informace o typu objektu za behu programu. Pˇrekladaˇc generuje typove´ informace a ty jsou dostupne´ ˇ pˇri behu aplikace (RTTI = Run-Time Type Information)
void g(X *p) { const type_info &a = typeid(p); const type_info &b = typeid(*p);
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ˇ
// X* // tˇ rı ´da X // nebo odvozen´ a
}
141/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
142/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı Tˇr´ıda type info — pokraˇcovan´
Tˇr´ıda type info ´ Deklarovano v napˇr´ıklad takto: class type_info { // ... implementaˇ cnˇ e z´ avisl´ a reprezentace public: 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; // zak´ azan´ e operace: type_info(const type_info&) = delete; type_info & operator= (const type_info&) = delete; };
´ r C++ ICP — Seminaˇ
´ 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).
143/245
´ r C++ ICP — Seminaˇ
144/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ´ ı Operatory pro pˇretypovan´
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator const cast
const_cast(e)
const_cast < TYP > ( v´ yraz ) static_cast < TYP > ( v´ yraz ) reinterpret_cast < TYP > ( v´ yraz ) dynamic_cast < TYP > ( v´ yraz )
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.
ˇ k TYP(v´ Doplnek yraz) (nepouˇz´ıvejte (TYP)v´ yraz )
Nefunguje pro ukazatele na funkce a metody. ´ s puvodn Pouˇzit´ı v´ysledku pro praci eˇ konstantn´ımi daty ˚ ´ k nedefinovanemu ´ ´ ı. muˇ chovan´ ˚ ze vest ´ ´ ı respektuj´ı ’konstantnost’ Ostatn´ı operatory pˇretypovan´ ˇ a nemohou ji menit.
´ 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ˇ
145/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator static cast
146/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator reinterpret cast reinterpret_cast(e)
static_cast(e)
pˇretypuje e na typ T kdyˇz jde o konverzi ukazatelu˚ na:
pˇretypuje e na typ T pokud:
celoˇc´ıseln´y typ nebo enum a naopak ´ funkce ruzn typu ˚ eho
ˇ muˇ T pom(e); ˚ zeme deklarovat doˇcasnou promennou typ T je void
´ objekty ruzn typu (i reference) ˚ eho ´ cˇ leny tˇr´ıd ruzn typu ˚ eho
´ ı reference/ukazatele na (ne virtualn´ ´ ı) jde o pˇretypovan´ ´ bazovou tˇr´ıdu na referenci/ukazatel na odvozenou tˇr´ıdu
ˇ 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´
existuje inverzn´ı standardn´ı konverze, int→enum, void*→Cls*, D::*p→B::*p ˇ jinak dojde k chybe.
´ r C++ ICP — Seminaˇ
´ Poznamka: V´ysledky reinterpret_cast se obvykle mus´ı ´ pˇretypovavat ´ ´ ı typ, aby byly pouˇzitelne. ´ dale na svuj ˚ originaln´ 147/245
´ r C++ ICP — Seminaˇ
148/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator reinterpret cast — pˇr´ıklad
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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*.
void f(char *p) { *p = ’x’; } typedef void (*FP) (const char*);
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ˇ ´ ı bude 0, v pˇr´ıpadeˇ – v´ysledna´ hodnota po pˇretypovan´ ´ reference je vyvolana v´yjimka bad_cast.
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ˇ
149/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Operator dynamic cast — pˇr´ıklad
´ Uvod Jazyk Knihovny C++11
ˇ ´ Sablony – zakladn´ ı pojmy
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Kl´ıcˇ ova´ slova: template, typename ˇ Sablony funkc´ı a metod ˇ Sablony tˇr´ıd ˇ Sablony statick´ych datov´ych cˇ lenu˚ tˇr´ıd, ... Alias deklarace sˇ ablon (using, pouze C++11) ´ cna´ specializace Instanciace, specializace a cˇ asteˇ ´ ı Metaprogramovan´
// implicitn´ ı pˇ retypov´ an´ ı
´ Poznamky: Definice v hlaviˇckov´ych souborech, ´ ı instanc´ı, typova´ kontrola, ruzn implicitn´ı/explicitn´ı generovan´ ˚ e´ optimalizace, moˇznost ”code bloat”, ...
D *pd1 = dynamic_cast(pb1); // 0 (nelze) D *pd2 = dynamic_cast(pb2); // uk. na objekt D } ´ r C++ ICP — Seminaˇ
150/245
sˇ ablona (template) = typ parametrizovan´y jin´ymi typy ´ ı Genericke´ programovan´
class B { // min. jedna virtu´ aln´ ı metoda virtual void m() {} }; class D : public B { // ... }; int main() { B *pb1 = new B; B *pb2 = new D;
´ r C++ ICP — Seminaˇ
151/245
´ r C++ ICP — Seminaˇ
152/245
´ Uvod Jazyk Knihovny C++11
ˇ Sablony – pˇr´ıklady
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Parametry sˇ ablon
Deklarace template template
ˇ Sablony lze parametrizovat:
R f(T); class Vector;
typem — napˇr´ıklad typename T nebo class T hodnotou — napˇr´ıklad int i Lze pouˇz´ıt pouze celoˇc´ıseln´y typ, 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.
Pouˇzit´ı sˇ ablon, dedukce, instanciace int i = f(3.14); // f double d = f<double,double>(3);
sˇ ablonou — napˇr´ıklad template class K
Vector vec1; Vector> vec2; // pozor na >> v C++89
ˇ Sablona muˇ ˚ ze m´ıt v´ıce parametru: ˚ template < typename T, T v, typename U > class S;
std::map<std::string,int> m; std::basic_string us;
´ r C++ ICP — Seminaˇ
153/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı Parametry sˇ ablon — pokraˇcovan´
´ r C++ ICP — Seminaˇ
154/245
´ Uvod Jazyk Knihovny C++11
ˇ Sablony funkc´ı
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Lze definovat implicitn´ı hodnoty parametru˚ sˇ ablon: Pˇr´ıklad: sˇ ablona max template T max(T x, T y) { return (x>y)?x:y; }
template< typename T = int, int v = 10 > class S; template< template class p = S > class X; ˇ Pˇr´ıklad: Sablona Buffer template< typename T = char, int size = 256 > class Buffer { // Definice... };
Pˇri prvn´ım pouˇzit´ı pˇrekladaˇc generuje odpov´ıdaj´ıc´ı funkci (instanci sˇ ablony) podle typu argumentu: ˚ int j = max(5,0); MyClass a, b; MyClass m = max(a,b);
// Pouˇ zit´ ı ˇ sablony: Buffer<> buf; // Buffer Buffer buf1; Buffer<std::string> buf2; // kapacita 256 ´ r C++ ICP — Seminaˇ
// definice
// 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 155/245
´ r C++ ICP — Seminaˇ
156/245
´ Uvod Jazyk Knihovny C++11
ˇ Sablony funkc´ı a funkce
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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(i,i) max(c,c); // vol´ a max(c,c) max(i,c); // nen´ ı funkce max(int,char) =chyba! max(c,i); // nen´ ı max(char,int) =chyba! }
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; }
Pokud bychom pˇredem explicitneˇ deklarovali funkci
const char *s = max("a", "aaa");
int max(int,int);
Potom ma´ tato funkce pˇrednost pˇred sˇ ablonou.
´ pˇr´ıpadeˇ se pouˇzije k chybeˇ by nedoˇslo, protoˇze v takovem konverze char na int.
ˇ zovan´ ´ ı funkc´ı ´ Poznamka: Pˇreteˇ
´ Poznamka: Parametry sˇ ablony lze dedukovat pouze podle ´ ´ argumentu˚ (ne podle navratov eho typu funkce). ´ r C++ ICP — Seminaˇ
157/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ Sablony tˇr´ıd — pˇr´ıklad Vector
158/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Specializace sˇ ablon – pˇr´ıklady ´ ıch pˇr´ıpadu: = explicitn´ı definice specialn´ ˚
template class Vector { T * data; int size; public: explicit Vector(int size); // ... operator[] atd. }; template Vector::Vector(int size) { // definice konstruktoru ˇ sablony } int main() { Vector x(5); // generuje instanci vektoru for(int i = 0; i<5; i++) x[i] = i; } ´ r C++ ICP — Seminaˇ
´ r C++ ICP — Seminaˇ
// Obecn´ a ˇ sablona: template T max(T x, T y) {return (x>y)?x:y;} // ˇ C´ asteˇ cn´ a (partial) specializace: template T* max(T*a, T*b) { /*...*/ } // 3 r˚ uzn´ e specializace: template<> char* max(int *a, int *b) {/*...*/} template<> int* max<>(char *a, char *b) { /*...*/ } template<> void* max(void *a, void *b) { /*...*/ } // Obecn´ a ˇ sablona Vector viz pˇ redch´ azej´ ıc´ ı slajd // ˇ C´ asteˇ cn´ a specializace: template class Vector { /*...*/ }; // Specializace: template<> class Vector { /*...*/ }; 159/245
´ r C++ ICP — Seminaˇ
160/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Specializace sˇ ablon
´ ´ ´ Problemem nasleduj´ ıc´ı ”genericke”implementace seznamu je ´ nemoˇznost typove´ kontroly vkladan´ ych prvku. ˚ class Glist { // data public: void insert(void *); void *get(); // ... dalˇ s´ ı operace };
Pouˇzije se vˇzdy nejv´ıce specializovan´y pˇr´ıpad: // k´ od: | co se pouˇ zije: //--------------------------------------------Vector v1; // obecn´ a ˇ sablona Vector Vector v2; // ˇ c´ asteˇ cn´ a specializace Vector v3; // specializace Vector ´ Identifikator sˇ ablony (Vector) nelze pouˇz´ıt bez specifikace ˇ parametru sˇ ablony <>, kromeˇ nekter´ ych pˇr´ıpadu˚ uvnitˇr popisu sˇ ablony. ´ r C++ ICP — Seminaˇ
´ Poznamka: Heterogenn´ı seznam ( void* )
161/245
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
162/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Poznamky
Pˇr´ıklad: Seznam s typovou kontrolou 2
ˇ Sablony lze definovat jen v hlaviˇckov´ych souborech ˇ (vyuˇzit´ı export bylo zapovezeno v C++11). Kaˇzda´ instance sˇ ablony ma´ svoje staticke´ prvky.
ˇ ı typove´ kontroly sˇ ablonou List: Doplnen´ template class List : public Glist { public: void insert(T *t) { Glist::insert(t); } T *get() { return (T *)Glist::get(); } // ... };
Je moˇzne´ definovat sˇ ablony metod (vˇcetneˇ konstruktoru). ˚ ´ ´ Pro jmena zavisl a´ na parametru sˇ ablony (dependent types) se pouˇz´ıvaj´ı kl´ıcˇ ova´ slova typename a template: template class X { typedef typename T::TypeU U; // vnoˇ ren´ y typ using TT = typename T::TypeTT; // lepˇ s´ ı, C++11 public: int m(U o) { T::template m<10>(); // ˇ sablona statick´ e metody } // ^ zde by byl probl´ em: operator < };
´ 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ˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: Seznam s typovou kontrolou
´ Specializace mus´ı nasledovat aˇz po definici obecne´ sˇ ablony ´ ı automatickemu ´ ´ ren´ı Definovane´ specializace zabran´ vytvaˇ instanc´ı z obecne´ sˇ ablony
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
163/245
´ r C++ ICP — Seminaˇ
164/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Poznamky
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Poznamky
Explicitn´ı instanciace sˇ ablony pro zadan´y typ: template class std::vector; Extern´ı deklarace sˇ ablony (nove´ v C++11):
´ STL (Standard Template Library) tvoˇr´ı zaklad standardn´ı knihovny jazyka ISO C++. ˇ Pouˇzit´ı sˇ ablon umoˇznuje nove´ pˇr´ıstupy — ´ ı, ruzn metaprogramovan´ ˚ e´ optimalizace, atd.
extern template class std::vector; ´ ı instanciaci v danem ´ modulu Pˇrekladaˇc neprovad´ (zrychlen´ı pˇrekladu). Alias templates (C++11) rˇeˇs´ı nedostatky typedef definic. Pˇr´ıklad:
SFINAE (Substitution Failure Is Not An Error) Pokud nelze rozvinout sˇ ablonu pro zadan´y typ, ale existuje jina´ pouˇzitelna´ alternativa, nejde o chybu. ˇ ˇ ym poˇctem parametru˚ (C++11 Variadic Sablony s promenn´ templates) TODO
template class S; template using ExtraS = S; // nelze s typedef
´ r C++ ICP — Seminaˇ
165/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Obsluha v´yjimek
166/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Pˇr´ıklad: tˇr´ıda Vector s kontrolou mez´ı indexu
ˇ Obsluha chyb vznikaj´ıc´ıch pˇri behu programu class Vector { int *p; int sz; public:
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
class Range {};
´ ı specialn´ ´ ı funkce, ktera´ chyby oˇsetˇr´ı (napˇr. matherr) Volan´
int &operator[] (int i) { if(i>=0 && i<sz) return p[i]; else throw Range(); // vznik v´ yjimky }
ˇ C++ umoˇznuje strukturovane´ ˇreˇsen´ı v´yjimeˇcn´ych situac´ı. Kl´ıcˇ ova´ slova: try throw catch ´ r C++ ICP — Seminaˇ
// typ v´ yjimky
— vymezen´ı obsluhovane´ oblasti ´ ı v´yjimky — generovan´ — zachycen´ı v´yjimky
// ... }; 167/245
´ r C++ ICP — Seminaˇ
168/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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 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 }
169/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
170/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ Pˇr´ıklad: tˇr´ıda Vector s kontrolou indexu a rozmeru
Rozliˇsen´ı v´yjimek
class Vector { int *p; int sz; public: static const int 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); };
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ˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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 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ˇ
´ Uvod Jazyk Knihovny C++11
171/245
´ r C++ ICP — Seminaˇ
172/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ Pˇr´ıklad: tˇr´ıda Vector s kontrolou indexu a rozmeru
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 } // .... };
´ 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.
´ ı ....pokraˇcovan´ 173/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
V´yjimky s parametry
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 }
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı V´yjimky s parametry — pokraˇcovan´
174/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı v´yjimek Sdruˇzovan´ Je moˇzne´ definovat hierarchie v´yjimek — napˇr: class class class class
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ˇ
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 } 175/245
´ r C++ ICP — Seminaˇ
176/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı v´yjimek Sdruˇzovan´
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ an´ ´ ı zdroju˚ Pˇridelov
´ ˇreˇsen´ı: Tradiˇcn´ı (nevhodne) ´ ı obsluhy v´yjimek prob´ıha´ v poˇrad´ı, ve Vyhodnocovan´ ´ jsou uvedeny pˇr´ıkazy catch. kterem
void use_file(const char *jmeno) { // pouˇ zit´ ı souboru FILE *f = fopen(jmeno,"r"); // otevˇ ren´ ı // pouˇ zit´ ı souboru f fclose(f); // uzavˇ ren´ ı }
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ˇ
V pˇr´ıpadeˇ v´yskytu v´yjimky uvnitˇr funkce je pˇreskoˇcen pˇr´ıkaz fclose a soubor zustane otevˇren! ˚
177/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ an´ ´ ı zdroju˚ 2 Pˇridelov
´ r C++ ICP — Seminaˇ
178/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ sen´ı pˇridelov ˇ an´ ´ ı zdroju˚ inicializac´ı (RAII) Reˇ
´ ı (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ˇ
RAII (Resource Acquisition Is Initialization) ´ ıch objektu: Zdroje ve formeˇ lokaln´ ˚ ˇ ı zdroje = inicializace (volan´ ´ ı konstruktoru) pˇridelen´ ˇ ı pˇri automatickem ´ volan´ ´ ı destruktoru na konci uvolnen´ bloku ´ eˇ i pˇri v´yskytu v´yjimky (viz dale) ´ Funguje spravn ´ Poznamka: Pouˇzit´ı napˇr. std::unique_ptr
179/245
´ r C++ ICP — Seminaˇ
180/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
ˇ an´ ´ ı zdroju˚ = inicializace (pˇr´ıklad) Pˇridelov
´ destruktory vˇsech Pˇri vzniku v´yjimky v konstruktoru jsou volany objektu, ˚ jejichˇz konstruktory byly bezchybneˇ dokonˇceny. ˇ an´ ´ ı pameti ˇ (s chybou) Pˇr´ıklad: pˇridelov class X { int *p; public: X(int s): p(new int[s]) ~X() { delete [] p; } // ... };
void use_file(const char *jmeno) { FilePtr f(jmeno,"r"); // otevˇ ren´ ı souboru // pouˇ zit´ ı souboru f } // automatick´ e uzavˇ ren´ ı souboru
{ init(); }
´ 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. 181/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Konstruktory, destruktory a v´yjimky
class FilePtr { // chov´ a se stejnˇ e jako FILE* FILE *p; public: FilePtr(const char *name, const char *atr) : p(fopen(name,atr)) { if(!p) throw FileError(); } ~FilePtr() { fclose(p); } operator FILE*() { return p; } }
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
182/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Specifikace v´yjimek
Bezpeˇcne´ ˇreˇsen´ı: template class MemPtr { T *p; public: MemPtr(size_t s) { p = new T[s]; } ~MemPtr() { delete [] p; } // TODO: copy-ctr, operator= operator T* () { return p; } }; class X { MemPtr cp; // ukazatel - objekt public: X(int s): cp(s) { init(); } };
Specifikace, zda funkce (ne)muˇ ˚ ze vyprodukovat v´yjimku. Pˇr´ıklad specifikace void f() noexcept; void g() noexcept(true); funkce f a g nemohou vyvolat v´yjimku. Funkce bez specifikace muˇ ˚ ze vyvolat jakoukoli v´yjimku: int h(); // m˚ uˇ ze vyvolat libovolnou v´ yjimku ´ Poznamky: C++98: dynamicke´ specifikace T f() throw(v1,v2); ´ ı typu funkce. Specifikace v´yjimek nen´ı souˇcast´
ˇ ı pameti. ˇ V´yjimka v init() vˇzdy vede ke korektn´ımu uvolnen´ ´ Poznamka: std::unique_ptr, shared_ptr ´ r C++ ICP — Seminaˇ
183/245
´ r C++ ICP — Seminaˇ
184/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Neoˇcekavan e´ v´yjimky – zastarale´ C++98, nepouˇz´ıvat
Specifikace v´yjimek 2
ˇ ı v´yznam volan´ ´ ı Existuje funkce set_unexpected, ktera´ men´ funkce unexpected typedef void(*PF_t)(); PF_t set_unexpected(PF_t); class STC { PF_t old; public: STC(PF_t 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 }
´ 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. ˇ Pozor na nekter e´ operace (napˇr. operator=)
´ r C++ ICP — Seminaˇ
185/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ´ Neoˇcekavan e´ v´yjimky — poznamky
186/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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:
pokud by se rethrow nevolalo z catch(...), doˇslo by ´ ı funkce terminate k vyvolan´ unexpected se nikdy nevrac´ı (mus´ı vyvolat v´yjimku, nebo terminate())
typedef void(*PF_t)(); // ukazatel na funkci PF_t set_terminate(PF_t); Implicitneˇ plat´ı, zˇ e unexpected() vola´ terminate() a terminate() vola´ abort()
... ´ ı (Neopatrneˇ pouˇzite´ specifikace v´yjimek vedou k volan´ ´ funkce unexpected, coˇz je obvykle neˇzadouc´ ı.)
ˇ s´ı kod, ´ vlastn´ı ´ Poznamka: Pouˇzit´ı v´yjimek vede na vetˇ ´ ı v´yjimky je pomale. ´ vyvolan´
´ r C++ ICP — Seminaˇ
187/245
´ r C++ ICP — Seminaˇ
188/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı Standardn´ı v´yjimky — pokraˇcovan´
Standardn´ı v´yjimky
<exception>: class exception class bad_exception
<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
b´ aze pro std v´ yjimky
: class bad_alloc : class bad_cast class bad_typeid
´ metodu ktera´ vrac´ı ˇretezec ˇ Vˇsechny tyto tˇr´ıdy maj´ı definovanu s popisem v´yjimky: virtual const char* what() const noexcept;
´ r C++ ICP — Seminaˇ
189/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ˇ cnost Nasobn a´ dediˇ
190/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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
´ Poznamky: Anglicky: ”multiple inheritance” ´ ı Poˇrad´ı tˇr´ıd v deklaraci nen´ı v´yznamne´ kromeˇ poˇrad´ı volan´ ˇ konstruktoru, ˚ destruktoru˚ a uloˇzen´ı v pameti. ´ ˇ cnosti: Pouˇzit´ı nasobn e´ dediˇ ´ lod’ + letadlo = hydroplan
objekt:
B
Pozor na konverze ukazatelu! ˚
C ´ r C++ ICP — Seminaˇ
Souvislosti: Java interface, private, ...
a b c 191/245
´ r C++ ICP — Seminaˇ
192/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ˇ cnost — moˇzne´ problemy ´ Nasobn a´ dediˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ˇ cnost — virtualn´ ´ ı baze ´ 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
class class class class
ˇ dvakrat ´ tuteˇ ´ z tˇr´ıdu lze jen nepˇr´ımo: Dedit class class class class
´ Uvod Jazyk Knihovny C++11
X { .... }; A : virtual X { .... }; B : virtual X { .... }; C : A,B { .... };
Tˇr´ıda C obsahuje pouze jednu instanci tˇr´ıdy X.
X { .... }; // b´ azov´ a tˇ r´ ıda A : X { .... }; B : X { .... }; C : A,B { .... };
´ ı ´ Poznamka: Moˇznost parametrizace konstruktoru virtualn´ ´ ´ bazove tˇr´ıdy X: C::C(): X(1), A(2), B(3) { .... }
Tˇr´ıda C obsahuje dveˇ instance tˇr´ıdy X.
´ r C++ ICP — Seminaˇ
193/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ı konstruktoru˚ a nasobn ´ ˇ cnost Poˇrad´ı volan´ a´ dediˇ
194/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Ukazatele na cˇ leny tˇr´ıd
´ ´ 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ˇ
´ r C++ ICP — Seminaˇ
ˇ zne´ ukazatele, nelze na neˇ aplikovat beˇ ˇ zna´ pravidla Nejde o beˇ ´ ı, nelze je konvertovat na void * pro pˇretypovan´ ´ operator prvn´ı operand druh´y operand .* objekt tˇr´ıdy T nebo odvo- ukazatel na cˇ len tˇr´ıdy T zene´ 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.
195/245
´ r C++ ICP — Seminaˇ
196/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Ukazatele na cˇ leny tˇr´ıd — pˇr´ıklad
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Ukazatele na cˇ leny tˇr´ıd — poznamky
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)();
´ 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.
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ˇ
197/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ ´ u˚ .* a ->* — pˇr´ıklad Zaklady pouˇzit´ı operator
198/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Prostory jmen (”namespaces”)
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ˇ
´ r C++ ICP — Seminaˇ
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
199/245
´ r C++ ICP — Seminaˇ
200/245
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
´ Uvod Jazyk Knihovny C++11
Prostory jmen (namespaces)
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Definice a pouˇzit´ı prostoru jmen namespace A { class String { /* ... */ }; void f(String); }
´ moˇznost definovat prostor po cˇ astech ´ ´ ı (nesm´ı se shodovat se jmenem ´ jmeno mus´ı b´yt unikatn´ tˇr´ıdy, objektu, typu, ...) definice prostoru jmen je deklarac´ı
namespace B { class String { /* ... */ }; void f(String); }
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(); }
void g() { A::String s; // explicitn´ ı kvalifikace A::f(s); }
// C-funkce f()
´ r C++ ICP — Seminaˇ
201/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Definice a pouˇzit´ı prostoru jmen
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Using deklarace using-deklarace: using jm´ eno-prostoru :: identifik´ ator ; using typename jm´ eno-prostoru :: identifik´ ator ;
ˇ Cleny prostoru jmen lze definovat vneˇ tohoto prostoru: void A::f(String s) { String ss = "aaa"; // ... }
202/245
// A::String
using deklarace nen´ı definic´ı, jsou dovoleny redundantn´ı ´ ı objekty ve funkci nebo tˇr´ıde) ˇ deklarace (ne pro lokaln´
// A::String
void h() { using A::String; using A::f;
´ Poznamka: extern, friend funkce
String s; f(s);
// A::String // A::f
} ´ r C++ ICP — Seminaˇ
203/245
´ r C++ ICP — Seminaˇ
204/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Using direktiva
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = 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 podobneˇ jako u prostoru jmen:
using-direktiva: using namespace jm´ eno-prostoru ;
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) // ... };
´ 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 } ´ Pokud jsou nalezeny stejne´ identifikatory ruzn´ ˚ ych objektu˚ ˇ zuj´ı) ve v´ıce prostorech jde o chybu. (funkce se pˇreteˇ using direktiva je tranzitivn´ı. ´ r C++ ICP — Seminaˇ
205/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Tˇr´ıdy a prostory jmen
206/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Nepojmenovan´y prostor jmen Symboly nejsou dostupne´ z jin´ych modulu˚ (jako static v C). namespace { void f(); }
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
void g() { f(); }
uvnitˇr tˇr´ıdy nelze definovat prostor jmen ˇ do v´ıce deklarac´ı prostor jmen tˇr´ıd nelze rozdelit
// 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ˇ
207/245
´ r C++ ICP — Seminaˇ
208/245
´ Uvod Jazyk Knihovny C++11
ˇ ˇ zovan´ ´ ı Dediˇ ˇ cnost Sablony = Objekty Pˇreteˇ V´yjimky =
Kl´ıcˇ ove´ slovo mutable
ISO C++11 zahrnuje standardn´ı knihovny ISO C99: rozhran´ı
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ˇ
209/245
210/245
´ Uvod Jazyk Knihovny C++11
std Boost
Pˇrehled standardn´ı knihovny C++ 1/4
co obsahuje
rozhran´ı <array> <deque> <exception>
´ s promenn´ ˇ ym poˇctem argumentu˚ prace ˇ Nekter a´ makra a datove´ typy. Definice pro standardn´ı vstup/v´ystup celoˇc´ıselne´ typy a meze Obecneˇ pouˇzitelne´ funkce ´ s ˇretezci ˇ ˇ ı. Funkce pro praci a pamet´ ´ s cˇ asem. Typy a funkce pro praci ´ s Unicode znaky prace ´ s wchar_t prace makra pro klasifikaci wchar_t
ˇ v prostoru jmen std. Vˇsechny definice jsou um´ısteny
´ r C++ ICP — Seminaˇ
co obsahuje ˇ ı. Makro assert pro laden´ Makra pro klasifikaci znaku. ˚ komplexn´ı cˇ ´ısla ´ konstanty – chybove´ kody Parametry a meze pro floating-point funkce pro floating-point prostˇred´ı ´ (v C++ je prazdn´ y) intmax_t atd rozsahy cel´ych cˇ ´ısel ´ narodn´ ı/jazykova´ podpora Matematicke´ funkce. Typy pro longjmp() a setjmp(). deklarace pro signal() a raise()
´ r C++ ICP — Seminaˇ
std Boost
Standardn´ı knihovny rozhran´ı <cuchar>
std Boost
Standardn´ı knihovny C++
´ 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.
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
211/245
´ r C++ ICP — Seminaˇ
co obsahuje algoritmy nad kontejnery std::array pole pevne´ velikosti atomicke´ operace ´ posloupnost bitu˚ pevne´ delky ´ s cˇ asem prace komplexn´ı cˇ ´ısla Unicode konverze ´ ı vlaken ´ podm´ınky pro cˇ ekan´ ˇ a´ fronta obousmern obsluha v´yjimek, terminate ˇ eˇ vazan´ ´ jednosmern y seznam soubory - vstup/v´ystupn´ı streamy ´ nastroje pro asynchronn´ı operace ´ ı, binarn´ ´ ı) funkˇcn´ı objekty (unarn´ 212/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
std Boost
Pˇrehled standardn´ı knihovny C++ 2/4 rozhran´ı <list> <map> <memory> <mutex>
Pˇrehled standardn´ı knihovny C++ 3/4
co obsahuje inicializaˇcn´ı seznam ´ manipulatory pro streamy ´ bazov a´ tˇr´ıda pro streamy forward deklarace pro streamy vstup/v´ystupn´ı streamy vstupn´ı streamy ´ iteratory implementaˇcn´ı limity (mezn´ı hodnoty) seznam (DLL) lokalizace asociativn´ı kontejner (kl´ıcˇ –hodnota) ´ pameti ˇ - alokatory, ´ sprava ... ´ ´ nastroje pro vzajemn e´ vylouˇcen´ı ´ dynamicke´ pameti ˇ sprava
´ r C++ ICP — Seminaˇ
rozhran´ı <set> <sstream> <stack> <stdexcept> <streambuf> <string> <system_error> 213/245
´ Uvod Jazyk Knihovny C++11
co obsahuje numericke´ operace (accumulate,...) v´ystupn´ı streamy fronta ´ ´ (pseudo)nahodn e´ generatory zlomky (compile-time) ´ ı v´yrazy regularn´ (multi)mnoˇzina - asociativn´ı kontejner ˇretezcov ˇ e´ streamy ´ zasobn´ ık standardn´ı typy v´yjimek ´ ˇ ’ pro streamy vyrovnavac´ ı pamet ˇ obecne´ ˇretezce (basic_string, ...) ´ ı chyb zpracovan´
´ r C++ ICP — Seminaˇ
214/245
´ Uvod Jazyk Knihovny C++11
std Boost
Pˇrehled standardn´ı knihovny C++ 4/4 rozhran´ı
std Boost
std Boost
Knihovny pro C++ ´ ´ Poznamka: STL — Standard Template Library — je zaklad ´ u, pro definice kontejneru, ˚ iterator ˚ algoritmu, ˚ atd.
co obsahuje ´ vlakna n-tice ´ pro type_info adapter typove´ informace, type_info is_class, is_array, ... ”hash”-tabulka ”hash”-mnoˇzina relaˇcn´ı operace pole hodnot vektor
ˇ ı to, co Na Internetu jsou dostupne´ dalˇs´ı knihovny, ktere´ doplnuj´ nen´ı ve standardn´ı knihovneˇ ISO C++: Grafika, GUI S´ıt’ova´ rozhran´ı ´ ı, vlakna ´ Paraleln´ı programovan´ Numericke´ metody ´ ı Metaprogramovan´ ´ ı textu Zpracovan´ ´ ı Testovan´ ...
ˇ v prostoru jmen std. Vˇsechny definice jsou um´ısteny
´ Poznamka: + nadstavby nad C knihovnami ´ r C++ ICP — Seminaˇ
215/245
´ r C++ ICP — Seminaˇ
216/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
std Boost
std Boost
´ Boost jako zaklad pro stdc++
Boost
ˇ Nekter e´ knihovny jsou v C++11:
http://www.boost.org/
´ <array> — obalka pro pole (ve stylu STL)
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++:
— ”hash”funkce, kontejnery ´ — pseudonahodn a´ cˇ ´ısla, rozloˇzen´ı
´ ı v´yrazy (regex), LL parser (spirit) regularn´ ´ vlakna (thread), s´ıt’ova´ komunikace (asio, MPI) ´ pseudonahodn a´ cˇ ´ısla (random), ruzn ˚ a´ rozloˇzen´ı matematika (math, uBLAS, quaternion, rational, ...) ´ ı obrazu (GIL), (geometry) zpracovan´ datove´ struktury (graph, bimap, circular buffer, dynamic bitset, ...) ´ n-tice, smart ptr, souborov´y system, datum a cˇ as, intervaly, lambda, dim. anal´yza (units) ´ ´ ı (MPL), navrhov e´ vzory (flyweight), metaprogramovan´ serializace, coroutine ... ´ r C++ ICP — Seminaˇ
— zlomky ´ ı v´yrazy — regularn´ ´ — vlakna — n-tice ´ (is_class, ...) — pro testy v sˇ ablonach ˇ <memory> — doplneno: shared_ptr, weak_ptr, ... ˇ — doplneno: std::bind, std::ref, std::mem_fun a mem_fun_ref 217/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
218/245
´ Uvod Jazyk Knihovny C++11
std Boost
std Boost
´ Boost lambda – problemy implementace
Boost lambda – pˇr´ıklady (zruˇsit) list v(10); for_each(v.begin(), v.end(), _1 = 1); // v[i] = 1
for_each(vp.begin(), vp.end(), cout << ’\n’ << *_1); // probl´ em: cout << ’\n’ se vyhodnot´ ı jen jednou
vector vp(10); transform(v.begin(), v.end(), vp.begin(), &_1); // napln´ ı vp ukazateli na prvky v
for_each(vp.begin(), vp.end(), cout<
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
A a; B b; ret(_1 + _2)(a, b); // ˇ reˇ sen´ ı (TODO: pouze v Boost)
sort(vp.begin(), vp.end(), *_1 > *_2); // ˇ rad´ ı vp - klesaj´ ıc´ ı velikost c´ ıl˚ u ukazatel˚ u
int i = 1; int j = 2; (_1 + _2)(i, j); // ok (_1 + _2)(1, 2); // chyba, ale nevad´ ı - nepouˇ z´ ıv´ a se
for_each(vp.begin(), vp.end(), cout << *_1 << ’\n’); // v´ ystup c´ ıl˚ u ukazatel˚ u ´ r C++ ICP — Seminaˇ
219/245
´ r C++ ICP — Seminaˇ
220/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
std Boost
tuples (n-tice)
std Boost
n-tice
n je omezeno implementac´ı (napˇr 0..10) (NE v C++11) 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)
// 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.
// default ctr tuple x = std::make_pair(1,’a’); // konverze // operace < == > <= >= !=
(lexikografick´ e uspoˇ r´ ad´ an´ ı)
tuple add_multiply_divide(int a, int b) { return make_tuple(a+b, a*b, double(a)/double(b)); } ´ r C++ ICP — Seminaˇ
221/245
´ Uvod Jazyk Knihovny C++11
´ r C++ ICP — Seminaˇ
222/245
´ Uvod Jazyk Knihovny C++11
std Boost
´ ı n-tice Specialn´
std Boost
Boost – shrnut´ı
int i; char c; double d; tie(i, c, a); // ekvivalent: make_tuple(ref(i), ref(c), ref(a));
Dalˇs´ı pˇr´ıklady viz WWW
// 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ˇ
´ je vhodne´ se s nimi Knihovny v Boost jsou velmi pouˇzitelne, ´ ´ seznamit i kdyˇz ne vˇsechny budou standardizovany.
( ) ’ ’
223/245
´ r C++ ICP — Seminaˇ
224/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
C++11 – R-hodnotove´ reference
C++11 – pˇrehled
ˇ e´ (nepojmenovane), ´ Reference na doˇcasne´ promenn ”perfect function forwarding”, ...
ˇ jazyka: Zmeny r-hodnotove´ reference (v´ykon) ´ lambda, vlakna, vylepˇsen´ı sˇ ablon, inicializace, ... Opravy chyb (explicit, ...) Ruzn ˚ a´ vylepˇsen´ı syntaxe (for, initializer_list,...) ...
typ:
Pˇr´ıklad: ”Move”konstruktor std::vector && f() { std::vector pom(10000); // ... return std::move(pom); // nekop´ ıruje data }
Vylepˇsen´ı C++98 knihoven Nove´ C++11 knihovny (z Boost)
´ r C++ ICP — Seminaˇ
T &&
225/245
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
226/245
´ Uvod Jazyk Knihovny C++11
C++11 – constexpr
C++11 – Inicializaˇcn´ı seznamy
Definice mus´ı b´yt pˇred pouˇzit´ım Implicitneˇ take´ const constexpr int get(constexpr int x) {return x;} int myarr[get(2+3) + 7]; int arr2[get(myarr[2])]; // Error: myarr nen´ ı constexpr
class SequenceClass { public: // initializer list constructor SequenceClass(std::initializer_list list); // ... }; SequenceClass x = {1, 2, 3, 4}; ´ r´ı pˇrekladaˇc a je konstantn´ı. Inicializaˇcn´ı seznam vytvaˇ
constexpr double acceleration_g = 9.8; constexpr double moon_gravity = acceleration_g / 6;
void function_name(std::initializer_list list); function_name({1.0f, -3.45f, -0.4f}); // vol´ an´ ı std::vector<std::string> v = { "aaa", "bbb", "ddd" }; std::vector<std::string> v{ "aaa", "bbb", "ddd" };
´ r C++ ICP — Seminaˇ
227/245
´ r C++ ICP — Seminaˇ
228/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
C++11 – jednotna´ inicializace kontejneru˚
C++11 – jednotna´ inicializace kontejneru˚
struct Struktura1 { // POD = Plain Old Data int x; double y; };
struct IdString { std::string name; int identifier; };
struct Struktura2 { Struktura2(int x, double y) : x_{x}, y_{y} {} private: int x_; double y_; };
IdString get_string() { return {"SomeName", 4}; // typ nen´ ı tˇ reba } std::vector v{4}; // POZOR! ini seznam std::vector v(4); // POZOR! 4 prvky
// stejn´ a inicializace: Struktura1 s1{2, 3.14}; Struktura2 s2{2, 3.14}; ´ r C++ ICP — Seminaˇ
229/245
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
C++11 – auto, decltype
C++11 – cyklus for
auto obj = boost::bind(&fce, _2, _1, neco); auto i = obj; for (auto i = C.cbegin(); i != C.cend(); ++i) { }
”range-based for” int pole[5] = {1, 2, 3, 4, 5}; for (int &x: pole) { x *= 2; }
decltype(a+1) val = a + 1; // decltype a auto se mohou liˇ sit: const std::vector v(1); auto a = v[0]; // a typu int decltype(v[0]) b = 1; // b typu const int& auto c = 0; decltype(c) e; decltype((c)) f = c; decltype(0) g; ´ r C++ ICP — Seminaˇ
// // // //
230/245
c e f g
typu typu typu typu
for (int i: {1, 2, 5, 10, 20, 50} ) ....
int int int&, (c) is an lvalue int, 0 is an rvalue
Funguje pro pole, inicializaˇcn´ı seznamy a vˇsechny kontejnery s begin() a end()
231/245
´ r C++ ICP — Seminaˇ
232/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
C++11 – lambda funkce
C++11 – lambda funkce
Funkˇcn´ı objekty [](int x, int y) { return x + y; }
Typicke´ pouˇzit´ı:
´ navratov´ y typ je decltype(x+y), omezen´ı na jeden pˇr´ıkaz
vector l; int sum = 0; for_each(l.begin(),l.end(), [&sum](int x){sum += x;});
´ Syntaxe pro explicitn´ı navratov´ y typ [](int x, int y) -> int { int z=x+y; return z+x; }
V metodeˇ je automaticky friend
”Closure”: [] = [x,&y] = [&] = [=] = ...
Typ funkˇcn´ıho objektu zna´ jen pˇrekladaˇc: bez dalˇ s´ ıch promˇ enn´ ych x hodnotou, y referenc´ ı vˇ sechny pouˇ zit´ e dalˇ s´ ı promˇ enn´ e odkazem vˇ sechny pouˇ zit´ e dalˇ s´ ı promˇ enn´ e hodnotou
´ r C++ ICP — Seminaˇ
auto lambda1 = [&](int x) { /*...*/ }; auto lambda2 = new auto([=](int x) { /*...*/ });
233/245
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
234/245
´ Uvod Jazyk Knihovny C++11
C++11 – alternativn´ı syntaxe funkc´ı
C++11 – delegace + konstruktory
Je nutne´ pro sˇ ablony. Napˇr´ıklad: template< typename L, typename R> auto afunc(const L &lh, const R &rh)->decltype(lh+rh) { return lh + rh; } ´ ˇ Definice vraceneho typu jsou pouˇzitelne´ obecne: struct Struct { auto fun(int x, int y) -> int; };
class C { int number; public: C(int new_n) : number(new_n) {} C() : C(42) {} // pouze C++11 }; ˇ en´ ˇ ı konstruktoru˚ Ded ˇ ´ Poznamka: Zmena v dokonˇcen´ı inicializace objektu – pozor
auto Struct::fun(int x, int y) -> int { return x + y; } ´ r C++ ICP — Seminaˇ
235/245
´ r C++ ICP — Seminaˇ
236/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
C++11 – silneˇ typovane´ v´ycˇ ty
C++11 – nullptr
enum class Enum1 { Val1, Val2, Val3 = 100, Val4 /* = 101 */ };
void foo(char *); void foo(int); foo(0); foo(nullptr); char *pc = nullptr; int *pi = nullptr; bool b = nullptr; int i = nullptr;
// int // ukazatel (probl´ em v C++98) // // // //
nejsou kompatibiln´ı s typem int Enum1::Val4 == 101 je chyba
OK OK OK hodnota false chyba
´ r C++ ICP — Seminaˇ
enum class Enum2 : unsigned int {Val1, Val2}; // pouˇ z´ ıt lze pouze s kvalifikac´ ı: Enum2::Val1 enum Enum3 : unsigned long {Val1 = 1, Val2}; // lze pouˇ z´ ıt Enum3::Val1 i Val1
237/245
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
238/245
´ Uvod Jazyk Knihovny C++11
ˇ C++11 – dalˇs´ı zmeny
ˇ ym poˇctem argumentu˚ C++11 – sˇ ablony s promenn´ ”Variadic templates” Pouˇzitelne´ pro definice n-tic:
´ >> v sˇ ablonach
template class tuple;
template class SomeType; std::vector<SomeType<(1>2)>> x1; // SomeType
tuple<> empty; tuple my_pair;
´ u˚ explicit u konverzn´ıch operator alias sˇ ablony ˇreˇs´ı nedostatky typedef
Je moˇzne´ definovat i typoveˇ bezpeˇcn´y printf:
template class S; template using TypedefName = S;
template void printf(const std::string &format, Params... par); Poˇcet typov´ych argumentu: ˚
using OtherType = void (*)(double);
// nov´ a syntaxe
long long z C99 ´ r C++ ICP — Seminaˇ
239/245
ICP
template struct SomeStruct { static const int size = sizeof...(Args); }; static_assert(SomeStruct::size == 2); ´ r C++ — Seminaˇ ...
240/245
´ Uvod Jazyk Knihovny C++11
´ Uvod Jazyk Knihovny C++11
ˇ ´ C++11 – ˇretezcov e´ literaly
u8"UTF-8 string." u"UTF-16 string." U"UTF-32 string."
´ C++11 – uˇzivatelske´ literaly
OutputType operator "" _suffix(const char *cstrliteral);
// const char[] // const char16_t[] // const char32_t[]
OutputType some_variable = 1234_suffix; // "1234"
u8"Unicode Character: \u2018"
// alternativa (nutn´ e pro constexpr) template OutputType operator "" _suffix();
”raw string literals”
OutputType some_variable = 1234_suffix; // operator "" _suffix<’1’, ’2’, ’3’, ’4’>()
R"(obsah ˇ retˇ ezce vˇ cetnˇ e \ a " )" u8R"XXX(cokoli vˇ cetnˇ e )" atd. )XXX"
´ r C++ ICP — Seminaˇ
Pˇ r´ ıklady pouˇ zit´ ı: 10kg + 1lb +100g + 1hrivna
241/245
´ r C++ ICP — Seminaˇ
´ Uvod Jazyk Knihovny C++11
242/245
´ Uvod Jazyk Knihovny C++11
C++11 – default/delete
C++11 – static assert
struct NonCopyable { NonCopyable & operator=(const NonCopyable&) = delete; NonCopyable(const NonCopyable&) = delete; NonCopyable() = default; }; struct NoInt { void f(double i); void f(int) = delete; };
Kontrola pˇri pˇrekladu: template struct Check { static_assert(sizeof(int) <= sizeof(T), "T is not big enough!"); };
struct OnlyDouble { void f(double d); template void f(T) = delete; }; ´ r C++ ICP — Seminaˇ
243/245
´ r C++ ICP — Seminaˇ
244/245
´ Uvod Jazyk Knihovny C++11
´ er ˇ Zav
V´yvoj jazyka C++ (C++17?) Nove´ knihovny (viz projekt Boost) http://www.boost.org/ Implementace pˇrekladaˇcu˚ a std knihoven (GCC, LLVM/clang, ...) Budoucnost C++
´ r C++ ICP — Seminaˇ
245/245