Historia wymaga pasterzy, nie rzeźników.

Jeżeli na liście typów nie ma żadnego typu (lista
jest pusta) to funkcja nie może zwrócić żadnego wyjątku. Należy pamiętać,
że gdy funkcja będzie próbowała wyrzucić wyjątek nieobsługiwanego typu
natychmiast zostanie wywołana funkcja biblioteczne unexpected(), która
wywoła funkcje abort(), która kończy wykonywanie programu.
Listing 11.13. Ograniczenia typów wyjątków zgłaszanych przez funkcję
#include <ios t r e am >
2 #i n cl u d e <c o n i o . h>
void t e s t ( int , char ) throw ( int , char , f l o a t ) ;
4
using namespace s t d ;
i n t main ( )
6
{ i nt i ;
char zn ;
11.5. Przechwytywanie wyjątków
247
8
c o u t << " Podaj ␣ l i c z b e ␣ : ␣ " ;
c i n >> i ;
10
c o u t << " Podaj ␣ znak ␣ : ␣ " ;
c i n >> zn ;
12
try
{ t e s t ( i , zn ) ;
}
14
catch ( i n t n )
{ c o u t << "Mamy␣ w y j a t e k ␣ typu␣ i n t ␣n␣=␣ " << n <<e n d l ; }
16
catch ( char z z )
{ c o u t << "Mamy␣ w y j a t e k ␣ typu␣ c h a r ␣ c ␣=␣ " << z z << e n d l ; }
18
catch ( f l o a t x )
{ c o u t << "Mamy␣ w y j a t e k ␣ typu␣ f l o a t ␣x␣=␣ " << x << e n d l ; }
20
g e t c h e ( ) ;
return 0 ;
22
}
void t e s t ( i n t i , char c ) throw ( int , char , f l o a t )
24
{
f l o a t x = 0 . 5 ∗ i ;
i f
( i == 0 ) throw i ;
26
i f ( c == ’ q ’ ) throw ’Q ’ ;
i f ( x < 1) throw x ;
28
}
Po uruchomieniu tego programu mamy wynik:
Podaj l i c z b e : 1
Podaj znak : s
Mamy w y j a t e k typu f l o a t x = 0 . 5
Z innym zestawem danych otrzymamy:
Podaj l i c z b e : 0
Podaj znak : r
Mamy w y j a t e k typu i nt n = 0
Widzimy, że pokazana funkcja test() poprawnie zgłasza wyjątki obsługiwane
przez bloki catch w funkcji main(). Ponieważ wyjątek może być dowolnego
typu, powszechną praktyka jest definiowanie klas, których obiekty będą za-
wierać dokładne informacje, które są przeznaczone do wyrzucenia a następ-
nie do obsłużenia przez instrukcję catch. W takich przypadkach mówimy, że
tworzymy klasy wyjątków.
W kolejnym przykładzie pokazujemy proste wykorzystanie klasy do ob-
sługi wyjątków. W programie obliczamy średnią harmoniczną (zmienna sh):
sh = 2.0 ∗ a ∗ b/(a + b);
(11.2)
Gdy liczba a = −b, otrzymamy zero w mianowniku i próbę dzielenia przez
zero, naszym zadaniem jest obsłużenie tego błędu.
248
11. Techniki obsługi błędów
Listing 11.14. Wykorzystanie klasy wyjątków
1 #i n cl u d e <i o s t r e a m >
#include <c o n i o . h>
3
using namespace s t d ;
5
c l a s s zly_wynik
{
7
private :
i n t x , y ;
9
public :
zly_wynik ( ) { } ;
11
zly_wynik ( i nt xx , i nt yy ) : x ( xx ) , y ( yy ) { } ;
void i n f o ( ) ;
13
} ;
15
void zly_wynik : : i n f o ( )
{ c o u t << " ␣x␣=␣ " << x << " ␣ ␣ " << " ␣y␣=␣ " << y
17
<< e n d l ;
c o u t << " ␣ Z l e ␣ dane ␣x␣=␣−y␣" << e n d l ;
19
}
21
i n t main ( )
{ i nt a , b ;
23
f l o a t sh ;
c o u t << " Podaj ␣ dwie ␣ l i c z b y : ␣ " ;
25
while ( c i n >> a >> b )
{ try
27
{ i f ( a == −b )
throw zly_wynik ( a , b ) ;
29
sh = 2 . 0 ∗ a∗b /( a+b ) ;
c o u t << " s r e d n i a ␣=␣ " << sh << e n d l ;
31
c o u t << " Podaj ␣ k o l e j n e ␣ dwie ␣ l i c z b y , ␣q␣ konczy , ␣ : ␣ "
<< e n d l ;
33
}
catch ( zly_wynik e r )
35
{ c o u t <<
"mamy␣ w y j a t e k " << e n d l ;
e r . i n f o ( ) ;
37
c o u t << " ␣ podaj ␣ k o l e j n e ␣ l i c z b y . \ n" ;
}
39
}
g e t c h e ( ) ;
41
return 0 ;
}
Po uruchomieniu tego programu mamy testowe wyniki:
Podaj dwie l i c z b y : 1
2
S r e d n i a harmoniczna = 1 . 3 3 3 3 3
Podaj k o l e j n e dwie l i c z b y , q konczy , :
11.5. Przechwytywanie wyjątków
249
1
−1
Mamy w y j a t e k
x = 1
y = −1
Z l e dane x = −y
Podaj k o l e j n e l i c z b y
q
Klasa wyjątku ma postać: