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. |