![]()
Výjimky umožňují v programu ošetřit množství chybových stavů. Chyba se může vytvořit během provádění programu. Například, když se program dotáže na zadání bodu v AutoCADu a uživatel stornuje akci výběru (tzn. nezadá žádný bod) je vygenerována chyba. C++ umožňuje takovéto chyby jednoduchým způsobem dynamicky detekovat a ošetřit. K detekci a ošetření chyb slouží v C++ tzv. správa chyb (exception handling).
Správa chyb je v C++ založena na koncepci předej a chyť (throw - and - catch). Throw - and - catch umožňuje metodě vrátit chybu pomocí příkazu throw, nebo ošetřit výskyt chyby pomocí příkazu catch.
try
{
pokusný_blok
}
catch (typ [identifikátor]) // musí navazovat na blok try
{
tělo_ošetření_výjimky
}
| pokusný_blok | |||
| Blok příkazů, které potřebujeme kontrolovat na výskyt chyby (výjimky). | |||
| typ | |||
|
Datový typ proměnné, která ponese informace o výjimce, často se označuje jako typ výjimky. Může být i reference. |
|||
| identifikátor | |||
| Identifikátor proměnné, která ponese informace o výjimce. Můžeme jej vynechat, ale pak nemůžeme objekt, který nese informace o výjimce v těle_ošetření použít. | |||
| tělo_ošetření_výjimky | |||
| Příkazy ošetřující výskyt výjimky. | |||
![]()
Nedojde-li k výskytu chyby (výjimky) v pokusném bloku, program přeskočí všechny bloky ošetřující výjimky a bude pokračovat prvním příkazem následujícím za nimi.
Vyskytne-li se v pokusném bloku chyba, funkce ve které se chyba vyskytla, vyvolá v reakci na tuto chybu výjimku. Přitom vytvoří instanci datového typu (libovolného), do které uloží informaci o chybě, která se objevila (pomocí příkazu throw). Program přeruší přirozený běh instrukcí a začne hledat odpovídající ovladač výjimky, který by výjimku ošetřil. Hledání probíhá v blocích, které příkaz throw dynamicky obklopují (začne hledat u aktuálního bloku, nenajde li ovladač zde postupuje do bloku, který obklopuje předchozí blok atd. Pokud není nalezen ovladač v aktuální pozici, přejde do funkce, která ji zavolala a tam opět postupuje v blocích. Pokud není nalezen ovladač ani zde opět přejde do nadřazené funkce atd. Pokud není nalezen odpovídající ovladač ukončí se program s chybou.
![]()
Na výjimku je možné pohlížet jako na další datový typ C++, který vrátí volaná metoda. Aby metoda mohla vrátit výjimku, musí při výskytu chyby vytvořit instanci nějakého datového typu, do které vloží informace o chybě, která se objevila. Výjimka se vyvolá pomocí klíčového slova throw.
throw výraz;
Výjimku je poté možné odchytit (zpracovat) pomocí příkazu catch.
main()
{
…
try
{
f();
}
catch (int n) { /* ošetření chyby */ }
…
}
void f()
{
…
if (chyba) throw 5;
…
}
Aby bylo možné ošetřit blok kódu na výskyt chyby, musí se hlídaný úsek kódu umístit do bloku příkazu try. Blok try sděluje C++, že má provádět příkazy v bloku kódu do té doby než se vygeneruje výjimka. Pokud se výjimka vyskytne, C++ opustí blok try a hledá příslušný blok kódu catch, který výjimku odchytne (zpracuje). Správný blok catch se pozná podle uvedeného typu výjimky uvedeného u příkazu catch (viz příklad). Blok catch se provede do konce a běh programu pokračuje. Pokud výjimka není v bloku try vygenerována, je blok catch při provádění programu přeskočen a pokračuje se dalšími příkazy za blokem catch.
try
{
// blok příkazů, které potřebujeme kontrolovat na výskyt výjimky
}
catch (typ_Vyjimky){ /*...*/}
{
printf("Byla odchycena výjimka typu typVyjimky");
}
příkaz throw odpovídající ovladače
throw 5; catch (int n) { … }
throw ‘a’; catch (char c) { … }
throw “Help!”; catch (const char *s) { … }
throw StackUnderfl(); catch (StackUnderfl& s) { … }
throw StackOverfl(n); catch (StackOverfl& s) { .. }
Při generování výjimky C++ hledá odpovídající blok catch. C++ pozná správný blok catch podle typu výjimky, který je deklarován v příkazu catch (viz předchozí příklad typ_Vyjimky). Pokud ho nenalezne, předá výjimku o úroveň výše ve volací hierarchii. Dostane-li se výjimka na vrchol hierarchie (hlavní funkce) a není ani zde zpracována, program vypíše chybovou zprávu a ukončí se.
C++ umožňuje efektivně zpracovat více typů výjimek vygenerovaných v jednom bloku try. Pokud potřebujete odchytit více typů výjimek v jednom bloku try stačí uvést za blok try více bloků catch (viz příklad).
![]()
try
{
// blok příkazů a metod pracujících se soubory
}
catch (int n) // odchytí výjimky typu throw číslo_int
{
printf("Byla odchycena výjimka typu EOFException");
}
catch (char c) // odchytí výjimky typu throw znak
{
printf("Byla odchycena výjimka typu FileNotFoundException");
}
catch (const char *s) // odchytí výjimky typu throw řetězec
{
printf("Byla odchycena výjimka typu FileNotFoundException");
}
Blok try může obsahovat libovolný počet příkazů, je však výhodnější do bloku try umísťovat příkazy, které spolu souvisí. Usnadňuje to následné ošetření výjimky v bloku catch.
![]()