O čem bude řeč
Již z nadpisu je asi jasné, že bude řeč o výjimkách v jazyku
C++. Tento miniseriál si neklade za cíl vysvětlit co to jsou výjimky, ale chce ukázat
jejich konkrétní aplikaci. Pokud jste o výjimkách v jazyce C++ neslyšeli, tak vám
asi bude článek dělat potíže.Text je spíše určen pro všechny z vás, kdo víte co
výjimky jsou, ale ještě jste jim nepřišli na chuť, nebo si nejste úplně jisti, k
čemu jsou dobré.
Postupně si zde vytvoříme příklad na použití výjimek. Začneme
řešením hrubou silou a skončíme u elegantního řešení.
Drobné opakování
Než začneme s příkladem, udělejme si malé opakování, které se
jistě bude hodit těm z vás, kdo výjimkám rozumí, kdysi je studovali, ale nějak si
teď nemohou vzpomenout jak ono to vlastně je.
try a catch
Část kódu, která může způsobit výjimku, se uzavírá do bloku,
který začíná klíčovým slovem try a je ukončen jednou nebo vícero sekcemi
catch. Každá ze sekcí catch odchytává různé výjimky podle typu.
Například takto:
try
{
// Voláme neco, co může generovat výjimku typu int
DoItOne();
// Voláme neco, co může generovat výjimku typu double
DoItTwo();
printf("Ales gute");
}
catch (int e)
{
// vznikla výjimka ve funkci DoItOne
printf("Vyjimka cislo %d", e);
}
catch (double e)
{
// vznikla výjimka ve funkci DoItTwo
printf("Vyjimka cislo %f", e);
}
printf("Hola hej", e); |
Pokud tedy vznikne výjimka ve funkci DoItOne, vykonávání
se převede na první catch a funkce DoItTwo se již nevyvolá, stejně
jako se nevytiskne řetězec Ales gute. Pokud vznikne výjimka ve funkci DoItTwo,
převede se řízení na druhý catch a řetězec Ales gute opět neuvidíme.
Pokud vše proběhne bez výjimečné události, pak se vytiskne naše Ales gute a kód
bude normálně pokračovat. Text "Hola hej" se vytiskne v každém případě.
throw
Víme tedy, jak výjimky různých typů odchytit. Nevíme (nebo si
nevzpomínáme) ale, jak je vyvolat. K tomu slouží klíčové slovo throw,
které pracuje podobně jako příkaz return, který je snad všem znám.
Příkaz throw generuje výjimku typu, jakého je uvedený výraz za klíčovým
slovem throw. Stejně jako u příkazu return je funkce ihned ukončena.
Pozor: typ generované výjimky a návratová hodnota spolu nijak nesouvisí. Funkce DoItOne
a DoItTwo by mohly vypadat třeba takto:
void DoItOne()
{
int x;
if ( <něco je špatně> )
{
x = 15; // chyba číslo 15
throw x;
}
if ( <neco jiného je špatne> )
{
x = 10; // chyba číslo 10
throw x;
}
}
void DoItTwo()
{
double x;
if ( <neco je špatne> )
{
x = 125.8;
throw x;
}
} |
Pokus prvý
Výjimky jsme si zopakovali a teď se podíváme, jak bychom je
použili. Zůstaneme u funkcí DoItOne a DoItTwo, tak jak jsme si je
definovali. Představme si, že první funkce navazuje spojení s nějakým serverm a
druhá funkce provádí komunikaci. V dalším kódu, který si uvedeme, nevypadá
použití výjimek nijak vábně a asi nepřesvědčí toho, kdo výjimky odmítá
používat. Berte to tak, že je to učebnicový příklad, který se snaží být co
nejjednodušší..
try
{
DoItOne();
DoItTwo();
}
catch (int e)
{
// vznikla výjimka ve funkci DoItOne
if (e==10)
printf("Neexistujici server\n");
else if (e==15)
printf("Chybne spojeni\n");
else
printf("Nezname cislo chyby\n");
}
catch (double e)
{
// vznikla výjimka ve funkci DoItTwo
if (e==125.8)
printf("Chybna rychlost spojeni 125 kB\n");
else
printf("Nezname cislo chyby\n");
} |
Kdybychom měli vyjmenovat všechny chyby, který uvedený kód má,
asi bychom vytvořili dlouhý seznam. Zkusme tedy jít dál, ale až v dalším dílu. |