PB161 Programování v jazyce C++ Přednáška 9

Podobné dokumenty
PB161 Programování v jazyce C++ Přednáška 9

PB161 Programování v jazyce C++ Přednáška 8

PB161 Programování v jazyce C++ Přednáška 5

PB přednáška (19. října 2015)

PB161 Programování v jazyce C++ Přednáška 4

PB161 Programování v jazyce C++ Přednáška 4

PB161 Programování v jazyce C++ Přednáška 10

PB161 Programování v jazyce C++ Přednáška 10

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

Programování v C++ 1, 17. cvičení

PB161 programování v C++ Výjimky Bezpečné programování

Ošetření chyb a výjimky

Jazyk C++ II. Výjimky

Programování v C++ 1, 5. cvičení

Více o konstruktorech a destruktorech

PREPROCESOR POKRAČOVÁNÍ

PB161 Programování v jazyce C++ Přednáška 5

Pokročilé programování v jazyce C pro chemiky (C3220) Pokročilá témata jazyka C++

PB161 Programování v jazyce C++ Přednáška 7

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

PB přednáška (12. října 2015)

Programování v C++ 3, 3. cvičení

Jazyk C++ I. Šablony 2

Programování v C++ 2, 4. cvičení

přetížení operátorů (o)

Abstraktní třídy, polymorfní struktury

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

PB161 Programování v jazyce C++ Přednáška 2

10. března 2015, Brno Připravil: David Procházka. Programovací jazyk C++

PB161 Programování v jazyce C++ Přednáška 9

Připravil: David Procházka. Programovací jazyk C++

Dědění, polymorfismus

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Z. Kotala, P. Toman: Java ( Obsah )

PB161 Programování v jazyce C++ Přednáška 1

PB161 Programování v jazyce C++ Přednáška 2

PB přednáška (23. listopadu 2015)

Zpracoval:

PB161 Programování v jazyce C++ Přednáška 7

Generické programování

PB161 Programování v jazyce C++ Přednáška 1

přetížení operátorů (o)

8 Třídy, objekty, metody, předávání argumentů metod

Dědičnost (inheritance)

Základy C++ I. Jan Hnilica Počítačové modelování 18

Programování v C++ 2, 8. cvičení

PB161 Programování v jazyce C++ Přednáška 3

Dynamika objektů. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

IUJCE Přednáška č. 11. další prvky globální proměnné, řízení viditelnosti proměnných, funkcí

Hrátky s funkcemi. PV173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 29.

Funkční objekty v C++.

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

PROGRAMOVÁNÍ V C++ CVIČENÍ

Programování v C++ 1, 6. cvičení

map, multimap - Asociativní pole v C++.

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

PB161 Programování v jazyce C++ Přednáška 3

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Teoretické minimum z PJV

Základy jazyka C# Obsah přednášky. Architektura.NET Historie Vlastnosti jazyka C# Datové typy Příkazy Prostory jmen Třídy, rozhraní

Šablony, kontejnery a iterátory

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

IB111 Úvod do programování skrze Python Přednáška 7

Jazyk C# (seminář 6)

Jazyk C++, některá rozšíření oproti C

Vector datový kontejner v C++.

Java Výjimky Java, zimní semestr

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

PB161 Programování v jazyce C++ Přednáška 3

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Jazyk C++ I. Polymorfismus

C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19

Úvod do programovacích jazyků (Java)

Jazyk C++ I. Šablony

Ukazka knihy z internetoveho knihkupectvi

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

Úvod do programovacích jazyků (Java)

Osnova přednášky. Programové prostředky řízení Úvod do C# II. Přístup ke členům. Členy (Members)

Syntaxe vyjímek. #include <iostream> #include <string> using namespace std; // Trida vyjimek class Vyjimka { private:

Dynamická identifikace typů v C++.

Konstruktory a destruktory

C++ objektově orientovaná nadstavba programovacího jazyka C

Jazyk C++ II. Šablony a implementace

Standardní algoritmy vyhledávací.

Zápis programu v jazyce C#

PŘETĚŽOVÁNÍ OPERÁTORŮ

Programování v C++ VI

C++ Akademie SH. 2. Prom nné, podmínky, cykly, funkce, rekurze, operátory. Michal Kvasni ka. 20. b ezna Za áte níci C++

konstruktory a destruktory (o)

Výjimky a ošetřování chyb v PHP. Who is General Failure and why is he reading my disk?!

Výjimky. Tomáš Pitner, upravil Marek Šabo

Ukazatele, dynamická alokace

Programování v Javě I. Únor 2009

Soubor jako posloupnost bytů

Jazyk C++ 1. Blok 3 Objektové typy jazyka C++ Třída. Studijní cíl. Doba nutná k nastudování. Průvodce studiem

Kolekce, cyklus foreach

Transkript:

PB161 Programování v jazyce C++ Přednáška 9 Jmenné prostory Výjimky podrobně Nikola Beneš 20. listopadu 2018 PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 1 / 32

Jmenné prostory PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 2 / 32

Motivace Problém: výskyt dvou entit se stejným jménem // library1.h class Object { /*... */ ; // library2.h class Object { /*... */ ; // main.cpp #include "library1.h" #include "library2.h" Při překladu main.cpp dojde k chybě: error: redefinition of class Object PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 3 / 32

Implicitní jmenné prostory globální jmenný prostor int x; // double x; // CHYBA! class Example { jmenný prostor třídy Example float x; public: void method() const { jmenný prostor metody method double x; for (int i = 0; i < 3; ++i) { std::string x; jmenný prostor cyklu for { char x; jmenný prostor bloku ; PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 4 / 32

Jmenné prostory Přístup ke jmenným prostorům operátor :: int x = 17; class Example { int x = 29; public: void print() const { int x = 3; { int x = 9; cout << x << endl; // 9 cout << Example::x << endl; // 29 cout << ::x << endl; // 17 cout << x << endl; // 3 ; lecture09_01.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 5 / 32

Explicitní jmenné prostory Pojmenované jmenné prostory syntax: namespace jmeno {... namespace MyLib { void print(); namespace Experimental { // možno i vnořovat void print(); // namespace Experimental // namespace MyLib namespace MyLib { class Example { public: void print() const; ; // namespace MyLib lecture09_02.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 6 / 32

Explicitní jmenné prostory zpřístupnění Zpřístupnění jmenného prostoru plná kvalifikace std::string direktiva using namespace jmeno_prostoru; #include <string> string s; // CHYBA! void print() { using namespace std; string s; // OK int main() { string s; // CHYBA! PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 7 / 32

Explicitní jmenné prostory zpřístupnění (pokr.) deklarace using jmeno_prostoru::jmeno_entity má prioritu před using namespace #include "libadam.h" #include "libeve.h" using namespace Adam; // obsahuje funkci getapple(); using namespace Eve; // taky obsahuje getapple(); getapple(); // CHYBA! using Eve::getApple; getapple(); // OK, volá se Eve::getApple(); alias jmenného prostoru namespace SysWinWidget = System::Window::Widget; lecture09_03.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 8 / 32

Explicitní jmenné prostory zpřístupnění Používání using a using namespace v globálním prostoru užívejte rozumně nikdy v hlavičkových souborech vždy až po všech #include lokálně ve funkcích/metodách ve vnořených blocích není možno používat přímo uvnitř třídy (class scope) PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 9 / 32

Explicitní jmenné prostory použití Použití jmenných prostorů ve vlastních knihovnách: // cool_library.h #ifndef COOL_LIBRARY_H #define COOL_LIBRARY_H namespace CoolLibrary { class Cool { /*... */ ; // namespace CoolLibrary #endif PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 10 / 32

Anonymní jmenné prostory namespace { //... // namespace chová se jako by se vytvořil jmenný prostor unikátního jména, za kterým by okamžitě následovalo using namespace k čemu je to dobré? zapouzdření identifikátorů uvnitř jednoho zdrojového souboru (resp. překladové jednotky) při linkování nejdou vidět z ostatních překladových jednotek podobné jako globální static v C, ale lepší proč? globální static funguje pouze pro proměnné a funkce, do anonymního namespace můžeme ale zavřít libovolná jména (např. deklarace typů) PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 11 / 32

Jmenné prostory další informace Další čtení pro zvídavé http://en.cppreference.com/w/cpp/language/namespace http://en.cppreference.com/w/cpp/language/lookup qualified name lookup unqualified name lookup argument-dependent lookup (ADL) namespace Test { int x; void print(int y) { int main() { print(x); // CHYBA! Test::print(x); // CHYBA! Test::print(Test::x); // OK print(test::x); // taky OK, ADL lecture09_04.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 12 / 32

Výjimky PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 13 / 32

Motivace Obsluha chyb za běhu programu možná řešení: speciální chybová hodnota, globální příznak kód se hůře čte a píše chyby jsou implicitně ignorovány které volání selhalo? co když je třeba chybu propagovat skrze víc funkcí? výjimky výjimečné situace za běhu programu vyhození výjimky (throw) zachycení výjimky (catch) a reakce i jinde než v místě výjimky používáno ve velké řadě jazyků PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 14 / 32

Syntaxe výjimek v C++ Vyhození výjimky throw výjimkou může být libovolná hodnota raději však používáme speciální objekty ve standardní knihovně std::exception void sillyfunction(int x) { if (x < 0) throw std::runtime_error("x is negative"); Zachycení výjimky try {... catch (... ) {... int main() { try { sillyfunction(-7); catch (std::runtime_error& ex) { std::cout << "Runtime error: " << ex.what() << '\n'; lecture09_05.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 15 / 32

Syntaxe výjimek v C++ (pokr.) Zachycení výjimky catch má formální parametr, kterým se má výjimka zachytit zachycení hodnotou nedoporučované, může znamenat kopii zachycení referencí doporučovaný způsob zachytávání libovolné výjimky pomocí catch (...) reakce v bloku catch vyřešení problému znovu vyhození stejné výjimky pomocí throw; vyhození jiné výjimky Throw by value, catch by reference. PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 16 / 32

Mechanismus zachytávání výjimek 1 vyhodí se výjimka 2 prochází se skrz zásobník funkcí, dokud se nenarazí na blok try 3 hledá se související blok catch, který může výjimku zachytit stejný typ výjimky a parametru parametr je reference na typ výjimky parametr je předek typu výjimky (reference, ukazatel) (...) chytá vše 4 pokud se najde správný blok catch: volají se destruktory lokálních objektů na zásobníku tzv. odvinování zásobníku (stack unwinding) nakonec se provede tělo bloku catch 5 pokud se správný blok catch nenajde, pokračuje se s hledáním od bodu 2 6 pokud se výjimka nezachytí nikde, zavolá se std::terminate v tom případě se destruktory nemusí zavolat lecture09_06.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 17 / 32

Standardní výjimky Hierarchie výjimek standardní knihovny základní std::exception virtuální metoda what() vrací popis výjimky vyhazovány standardní knihovnou př. metoda at() kontejnerů vyhazovány některými konstrukcemi jazyka C++ operátor new může vyhodit std::bad_alloc operátor dynamic_cast může vyhodit std::bad_cast PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 18 / 32

Standardní výjimky (pokr.) Výjimka při nepodařené alokaci int main() { const size_t SIZE = 1000; try { auto array = std::make_unique<int[]>(size); // není třeba testovat na nullptr for (int i = 0; i < SIZE; ++i) { array[i] = i*i; // atd... catch (std::bad_alloc&) { std::cerr << "Failed to allocate memory.\n"; lecture09_07.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 19 / 32

Vlastní výjimky doporučeno: dědit ze standardních výjimek class WrongNameException : public std::invalid_argument { std::string name; public: WrongNameException(const std::string& reason, const std::string& n) : std::invalid_argument(reason), name(n) { const std::string& getname() const { return name; ; class Person() { std::string name; static bool isvalidname(const std::string&); public: Person(const std::string& n) : name(n) { if (!isvalidname(name)) throw WrongNameException("invalid name", name); //... lecture09_08.cpp ; PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 20 / 32

Výjimky a dědičnost při zachytávání můžeme použít typ předka zachytávání probíhá v pořadí bloků catch v kódu doporučení: řadit bloky catch od konkrétních k obecným try { //... catch (std::invalid_argument&) { //... catch (WrongNameException&) { //... // warning: exception of type 'WrongNameException' will be // caught by earlier handler for 'std::invalid_argument' lecture09_08.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 21 / 32

Zachycení libovolné výjimky Zachycení pomocí catch (...) nemáme přístup k objektu výjimky alespoň ne úplně snadný odvážní mohou zkusit hledat std::current_exception (C++11) používat opatrně v některých specifických případech se ale hodí např. obalení těla destruktoru použití s opětovným vyhozením throw; logování problémů speciální funkce pro řešení výjimek lecture09_09.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 22 / 32

Výjimky a konstruktory Je vhodné vyhazovat výjimku z konstruktoru? ANO Kdy? pokud nemůžeme zaručit správný (konzistentní) stav objektu Co se stane? nezavolá se destruktor objektu zavolá se destruktor všeho, co už bylo inicializováno (předci, atributy) v opačném pořadí inicializace Jak zachytit výjimku v konstruktoru? normálně pomocí try... catch Co když je výjimka vyvolána při inicializaci? lecture09_10.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 23 / 32

Výjimky a konstruktory (pokr.) Speciální syntax pro konstruktory class Person { std::string name; public: Person(const std::string& n) : name(n) { ; class Teacher : public Person { std::vector< Course > courses; Person& departmentboss; public: Teacher(const std::string& name, Person& boss) try : Person(name), departmentboss(boss) { courses.reserve(5); catch (std::exception& ex) { std::cerr << "Teacher constructor failed: " << ex.what() << std::endl; ; lecture09_11.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 24 / 32

Výjimky a konstruktory (pokr.) Speciální syntax pro konstruktory použitelná i pro jiné metody/funkce, ale tam nemá moc význam destruktory předků a atributů se volají před blokem catch blok catch musí znovu vyhodit výjimku implicitní throw; na konci bloku hlavní použití: logování nebo úprava výjimek PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 25 / 32

Výjimky a destruktory Je vhodné vyhazovat výjimku z destruktoru? NE když v průběhu zachycení výjimky vznikne další výjimka, zavolá se std::terminate PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 26 / 32

Specifikace noexcept úmysl nevyhazovat z funkce/metody žádnou výjimku void f(); // může vyhodit libovolnou výjimku void g() noexcept; // slibuje, že nebude vyhazovat výjimky kompilátor může tuto informaci použít pro optimalizace standardní knihovna může tuto informaci použít pro volbu chování operátor noexcept std::cout << boolalpha; std::cout << noexcept( 2 + 3 ) << '\n'; // true std::cout << noexcept( throw 17 ) << '\n'; // false std::cout << noexcept( f() ) << '\n'; // false std::cout << noexcept( g() ) << '\n'; // true co když g() přesto vyhodí výjimku? destruktory jsou automaticky noexcept std::terminate PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 27 / 32

Výjimky při vstupu a výstupu Knihovna iostream implicitně nepoužívá výjimky, ale nastavuje příznaky důvody historické ne vždy je vhodné používat výjimky pro vstup a výstup použití výjimek je možno vynutit pomocí metody exceptions příznaky typu std::ios_base::iostate, kombinace pomocí výjimka typu std::ios_base::failure lecture09_12.cpp PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 28 / 32

Doporučení výjimkami řešte výjimečné situace chyby, špatné parametry, apod. tam, kde je jiné řešení nemožné/nevhodné (konstruktory, operátory) nepoužívejte výjimky pro vracení hodnot z funkcí a metod nenalezení prvku v poli nemusí být výjimečná situace házejte hodnotou, chytejte referencí zachytávání výjimek v inicializaci konstruktorů používejte, pokud chcete logovat nebo nějak měnit zachycenou výjimku nevyhazujte výjimky z destruktorů chytejte výjimky jen tehdy, pokud máte na výjimku jak rozumně reagovat PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 29 / 32

Závěrečný kvíz https://kahoot.it PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 30 / 32

Závěrečný kvíz (kód č. 1) void print() { std::cout << "x"; namespace A { void print() { std::cout << "y"; namespace B { void print() { ::print(); // namespace B // namespace A namespace C { void fun() { using namespace A; A::print(); B::print(); // namespace C int main() { using namespace C; print(); fun(); PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 31 / 32

Závěrečný kvíz (kód č. 2) class A { /*... */ ; class B : public A { /*... */ ; class C : public B { /*... */ ; class D { /*... */ ; void foo() { D d; throw B(); int main() { try { foo(); catch (C& ex) { cout << 1; catch (A& ex) { cout << 2; catch (B& ex) { cout << 3; PB161 přednáška 9: jmenné prostory, výjimky 20. listopadu 2018 32 / 32