| Časová náročnost: 25 minut |
V jazyce C++ existuje mechanismus, který slouží k obsluze chyb. Nazývá se
obsluha výjimek. Obsluha výjimek je založena na třech klíčových slovech:
|
- Try - zde uvádíme všechny výjimky, které chceme monitorovat
- Catch - popisuje jak reagovat na vzniklé výjimky
- Throw - slouží k zahazování (odmítnutí) výjimek
Všechny příkazy programu, které chceme monitorovat se zapíší do bloku try. Příkaz který odmítá výjimku musí být v bloku try umístěn. Výjimka musí být zachycena příkazem catch, který následuje bezprostředně za příkazem try.
Syntaxe je následující:
|
|
try {
// blok try
}
catch (typ1 argument) {
// blok catch
}
catch (typ2 argument) {
// blok catch
}
.
.
.
catch (typN argument) {
// blok catch
}
Blok try musí obsahovat tu část programu, kterou chceme monitorovat na výskyt chyb. Když je výjimka odmítnuta,je zachycena odpovídajícím příkazem catch přidruženým k try. Jaký příkaz catch to bude konkrétně určuje typ výjimky - přesněji se porovná typ dat specifikovaný v catch s typem ve výjimce a pokud je nalezena shoda,
provede se posloupnost příkazů.
Syntaxe příkazu throw je následující:
throw výjimka;
Příkaz throw musí být spuštěn buď z bloku try, nebo z nějaké funkce, kterou kód v bloku volá. Výjimka je odmítnutá hodnota.
Jestliže odmítneme výjimku, k níž neexistuje odpovídající příkaz catch může dojít k abnormálnímu ukončení programu.
Na prvním příkladu si ukážeme jak jazyk C++ přistupuje k výjimkám.
|
| Příklad 10.3. |
|
#include <iostream.h>
int main()
{
cout << "start\n";
try { // blok try
cout << "Uvnitr try\n";
throw 10; // odmitnuti chyby
cout << "Toto se nevytiskne";
}
catch (int i) { // zachyceni chyby
cout << "Zachycena chyba! Cislo je: ";
cout << i << "\n";
}
cout << "end";
return 0;
}
|
| Příklad: |
|
|
Jakmile je výjimka odmítnuta, předá se řízení výrazu
catch a blok
try je ukončen. Po provedení příkazu
catch pokračuje řízení programu příkazem následujícím za
catch.
Typ výjimky
musí souhlasit s typem specifikovaným ve výrazu
catch. Pokud tomu tak není, výjimka nebude zachycena a může dojít k chybnému ukončení programu.
Chybný příklad:
#include <iostream.h>
int main()
{
cout << "start\n";
try { // blok try
cout << "Uvnitr try\n";
throw 10; // odmitnuti chyby
}
// nebude fungovat pro vyjimku s datovym typem int
catch (double i) {
cout << "Zachycena chyba! Cislo je: ";
cout << i << "\n";
}
cout << "end";
return 0;
}
Někdy můžeme také chtít, abychom zachytávaly všechny výjimky - ne jen výjimky určitého typu. Použijeme následující formát
catch:
|
catch(...) {
// zpracování všech výjimek
}
Můžeme omezit typy výjimek, které může funkce odmítat zpět do jejich vyvolávače. Může také řídit, jaký typ výjimek, může funkce sama odmítat. Pro aplikaci určitých omezení musíme do definice funkce přidat klauzuli throw.
Syntaxe poté vypadá následovně:
|
|
návratový-typ jméno-funkce(argumenty) throw(seznam-typů)
{
// tělo funkce
}
Typy dat oddělené čárkou v poli seznam-typů mohou být funkcí odmítnuty. Pokud nechceme aby funkce zachytávala nějaké výjimky uvedeme prázdný seznam.
Následující příklad ukazuje zachycení všech výjimek - pouze u výjimky typu int bude vypsáno jiné hlášení.
|
| Příklad 10.4. |
|
#include <iostream.h>
void Xhandler(int test)
{
try{
if(test==0) throw test; // odmita int
if(test==1) throw 'a'; // odmita char
if(test==2) throw 123.23; // odmita double
}
catch(int i) { // zachytava vyjimky typu int
cout << "Zachycen int " << i << '\n';
}
catch(...) { // zachytava vsechny ostatni vyjimky
cout << "Zachyceno neco jineho nez int\n";
}
}
int main()
{
cout << "start\n";
Xhandler(0);
Xhandler(1);
Xhandler(2);
cout << "end";
return 0;
}
|
Následující příklad ukazuje jak lze omezit typy výjimek, které mohou být funkcí odmítnuty.
| Příklad 10.5. |
|
#include <iostream.h>
// Funkce odmita pouze int, char a double
void Xhandler(int test) throw(int, char, double)
{
if(test==0) throw test; // odmita int
if(test==1) throw 'a'; // odmita char
if(test==2) throw 123.23; // odmita double
}
int main()
{
cout << "start\n";
try{
Xhandler(0);
}
catch(int i) {
cout << "Zachyceno int\n";
}
catch(char c) {
cout << "Zachyceno char\n";
}
catch(double d) {
cout << "Zachyceno double\n";
}
cout << "end";
return 0;
}
|