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

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

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

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 5

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

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

Více o konstruktorech a destruktorech

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

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

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

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

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

Ošetření chyb a výjimky

Jazyk C++ II. Výjimky

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

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

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

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

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

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

Programování v C++ VI

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

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

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

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

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

Zpracoval:

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

Mělká a hluboká kopie

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

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

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

Konstruktory a destruktory

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

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

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

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

Šablony, kontejnery a iterátory

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

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

PB161 Programování v C++ Proudy pro standardní zařízení Souborové proudy Paměťové proudy Manipulátory

Generické programování

Funkční objekty v C++.

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

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

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

Abstraktní třídy, polymorfní struktury

Dynamická identifikace typů v C++.

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

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

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

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

Dědičnost (inheritance)

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

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

Šablony, kontejnery a iterátory

IUJCE 07/08 Přednáška č. 6

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.

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

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

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

Jazyk C++ I. Šablony 2

konstruktory a destruktory (o)

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

PROGRAMOVÁNÍ V C++ URČENO PRO VZDĚLÁVÁNÍ V AKREDITOVANÝCH STUDIJNÍCH PROGRAMECH ROSTISLAV FOJTÍK

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

Singleton obsah. Motivace Základní myšlenka Implementace Problémy. Dědičnost Obecná implementace Shrnutí. destrukce vícevláknovost

Cvičení z programování v C++ ZS 2016/2017 Přemysl Čech

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.

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

Vector datový kontejner v C++.

Dědění, polymorfismus

PREPROCESOR POKRAČOVÁNÍ

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

Správa paměti. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta, 2016

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

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

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

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

Zpracoval:

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

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

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

Semin aˇr Java V yjimky Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Unor 2008 Radek Koˇc ı Semin aˇr Java V yjimky 1/ 25

24. listopadu 2013, Brno Připravil: David Procházka

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

Úvod do programovacích jazyků (Java)

Jazyk C++ I. Šablony

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

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

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

Chování konstruktorů a destruktorů při dědění

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

Množina čísel int stl-set-int.cpp

Vstupní a vstupní proudy v C++

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

Algoritmizace a programování

IW5 - Programování v.net a C# 4 Pokročilé konstrukce C#

SYSTÉMOVÉ PROGRAMOVÁNÍ Cvičení č.1

Transkript:

.. PB161 Programování v jazyce C++ Přednáška 8 Výjimky Správa prostředků (RAII) Nikola Beneš 9. listopadu 2015 PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 1 / 24

. PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 2 / 24

Výjimky. PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 2 / 24

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 8: výjimky, RAII 9. listopadu 2015 3 / 24

int main() { try { sillyfunction( -7 ); catch (int e) { cout << "exception no.: " << e << endl; PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 4 / 24 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 42; Zachycení výjimky try {... catch (... ) {...

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 throw; vyhození jiné výjimky Throw by value, catch by reference. PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 5 / 24

Mechanismus zachytávání výjimek 1. vyhodí se výjimka 2. prochází skrz zásobník funkcí, dokud nenarazí na blok try odvinování zásobníku (stack unwinding) 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, provede se; pokud se nenajde, pokračuje se s odvinováním zásobníku (bod 2.) 5. pokud se výjimka nezachytí nikde, zavolá se std::terminate PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 6 / 24

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 8: výjimky, RAII 9. listopadu 2015 7 / 24

Standardní výjimky (pokr.) Výjimka při nepodařené alokaci int main() { const int SIZE = 1000; try { int * pole = new int[size]; // není třeba testovat na nullptr for (int i = 0; i < SIZE; ++i) pole[i] = i*i; // atd... delete [] pole; catch (std::bad_alloc &) { cerr << "Failed to allocate memory.\n"; PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 8 / 24

class Person() { std::string name; static bool isvalidname(const std::string &); public: Person(std::string n) : name(n) { if (!isvalidname(name)) throw WrongNameException("invalid name", name); //... ; PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 9 / 24 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, std::string n) : std::invalid_argument(reason), name(n) { const std::string & getname() const { return name; ;

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' PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 10 / 24

Zachycení libovolné výjimky Zachycení pomocí catch (...) nemáme přístup k objektu výjimky 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 PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 11 / 24

int main() { try { // some code //... catch (...) { handleexception(); PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 12 / 24 Zachycení libovolné výjimky (pokr.) void handleexception() { try { throw; catch (SomeException & ex) { //... catch (OtherException & ex) { //...

Výjimky a konstruktory Je vhodné vyhazovat výjimku z konstruktoru? PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 13 / 24

Výjimky a konstruktory Je vhodné vyhazovat výjimku z konstruktoru? ANO Kdy? pokud nemůžeme zaručit správný stav 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? PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 13 / 24

Výjimky a konstruktory Je vhodné vyhazovat výjimku z konstruktoru? ANO Kdy? pokud nemůžeme zaručit správný stav 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? PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 13 / 24

class Person { std::string name; public: Person(std::string n) : name(n) { ; class Teacher : public Person { std::vector< Course > courses; Person & departmentboss; public: Teacher(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; ; PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 14 / 24 Výjimky a konstruktory (pokr.) Speciální syntax pro konstruktory

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

Výjimky a destruktory Je vhodné vyhazovat výjimku z destruktoru? PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 16 / 24

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 8: výjimky, RAII 9. listopadu 2015 16 / 24

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 cout << boolalpha; cout << noexcept( 2 + 3 ) << endl; // true cout << noexcept( throw 17 ) << endl; // false cout << noexcept( f() ) << endl; // false cout << noexcept( g() ) << endl; // true co když g() přesto vyhodí výjimku? destruktory jsou automaticky noexcept PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 17 / 24

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 cout << boolalpha; cout << noexcept( 2 + 3 ) << endl; // true cout << noexcept( throw 17 ) << endl; // false cout << noexcept( f() ) << endl; // false cout << noexcept( g() ) << endl; // true co když g() přesto vyhodí výjimku? destruktory jsou automaticky noexcept std::terminate PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 17 / 24

Motivace správa prostředků Uvolnění prostředků paměť, otevřené soubory, zámky, síťová spojení, možné řešení: uvolňovat prostředky jak v bloku try, tak v bloku catch řešení v jiných jazycích: finally řešení v C++: Resource Acquisition Is Initialisation (RAII) používá se i v jiných jazycích (D, Ada, Rust) PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 18 / 24

RAII Princip RAII správa prostředku spjatá s životním cyklem objektu inicializace: získání prostředku destruktor: uvolnění prostředku ideálně: jeden objekt spravuje jeden prostředek Deterministické volání destruktorů na konci bloku při odvinování zásobníku destruktory potomků před destruktory předků opačné pořadí než konstruktory Jiný název: scope-based resource management (SBRM) PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 19 / 24

RAII (pokr.) Rozdíly proti finally lokalita: získávání/uvolňování prostředků na jednom místě stručnost: kód pro jeden druhu prostředku píšeme jednou Destruktory/kopírovací konstruktory/kopírovací operátor = třída spravující prostředek: Rule of three buď nekopírovat vůbec nebo definovat explicitní kopírování třídy, které nespravují prostředky: Rule of zero implicitní destruktor a kopírování V běžném kódu se téměř nikdy nestaráme o (de)alokaci paměti. PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 20 / 24

RAII Kde se používá RAII? skoro všude standardní knihovna string, vector a jiné kontejnery vstupně/výstupní proudy chytré ukazatele (C++11) unique_ptr a spol. zamykání, mutexy (C++11) PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 21 / 24

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 PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 22 / 24

int main() { try { ifstream input("soubor.txt"); input.exceptions( ifstream::failbit ifstream::badbit ); // read from the file // the file is automatically closed catch (ios_base::failure & ex) { cerr << "I/O exception: " << ex.what(); PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 23 / 24 Výjimky při vstupu a výstupu (pokr.) #include <iostream> #include <fstream> using namespace std;

Shrnutí 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 není 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ů používejte RAII ideálně: jeden objekt jeden prostředek PB161 přednáška 8: výjimky, RAII 9. listopadu 2015 24 / 24