22.1 Zgłaszanie wyjątków
Dalej: 22.2 Wychwytywanie wyjątków
W górę: 22. Wyjątki
Wstecz: 22. Wyjątki
22.1 Zgłaszanie wyjątków
W dowolnym miejscu programu może być zgłoszony (wysłany)
wyjątek (ang. throwing lub
raising an exception). Często nawet nie wiemy, że
funkcja biblioteczna, którą wywołujemy, może to zrobić.
Lepiej jednak o tym wiedzieć. Autor takiej funkcji bibliotecznej nie
znał naszego programu, więc nie mógł wiedzieć, jak obsłużyć
daną sytuację wyjątkową. Aby nie przerywać programu, zgłasza więc
wyjątek, a użytkownik korzystający z tej funkcji wiedząc, że taki
wyjątek może zostać przez funkcję zgłoszony, sam definiuje
sposób jego obsługi. Widzimy zatem, że mechanizm obsługi wyjątków
daje możliwość pewnego rodzaju komunikacji między różnymi
fragmentami kodu, być może pochodzącymi z różnych modułów
i napisanych przez różnych autorów.
W funkcjach, które sami piszemy, możemy określić, kiedy i jaki
wyjątek zostanie zgłoszony. Wyjątek może być opisany obiektem
dowolnego typu, klasowego lub wbudowanego. Zazwyczaj tworzy się
specjalne klasy, których obiekty będą opisywać wyjątki. Równie
dobrze jednak wyjątek może być opisany po prostu liczbą lub napisem.
Wyjątek jest zgłaszany za pomocą operatora
throw:
throw excpt;
gdzie
excpt może być obiektem dowolnego typu, również
wbudowanego, jak
int czy
double.
W momencie zgłoszenia wyjątku normalny przebieg programu jest
przerywany i poszukiwana jest procedura obsługi danego wyjątku (czyli
odpowiednia fraza
catch, o czym powiemy w następnym
podrozdziale). Jeśli taka procedura zostanie znaleziona, to wyjątek
uważa się za obsłużony i wykonywana jest treść procedury.
Nie ma automatycznego powrotu do miejsca zgłoszenia wyjątku!
Jeśli taka procedura nie zostanie znaleziona
w funkcji, w której ta sytuacja wyjątkowa miała miejsce, to
przepływ sterowania opuszcza kod funkcji, a ramka stosu związana z jej
wywołaniem jest usuwana (stos jest „zwijany'').
Oznacza to, między innymi, że zmienne lokalne zdefiniowane w tej
funkcji są bezpowrotnie tracone. Dla usuwanych lokalnych zmiennych
obiektowych wywoływane są, co bardzo ważne, ich destruktory. Jeśli
funkcja była rezultatowa, to wartość zwracana jest nieokreślona
i wobec tego bezużyteczna. Na tej samej zasadzie poszukiwanie procedury
obsługi jest następnie kontynuowane w funkcji wywołującej. Jeśli
i tam nie zostanie znaleziona, to i ta funkcja przerywa swoje działanie
i jej ramka wywołania na stosie jest też zwijana. W ten sposób mamy
dwie możliwości:
Odpowiednia procedura obsługi zostanie w końcu znaleziona.
Wtedy sterowanie przechodzi do wykonania tej procedury, a
następnie, jeśli program nie został w tej procedurze
przerwany, jest kontynuowany od miejsca w programie za
procedurą obsługi. Pamiętajmy, że nie ma powrotu
do miejsca w programie, w którym nastąpiło zgłoszenie
wyjątku (mówimy, że mechanizm obsługi wyjątków jest
w C++ niewznawialny);
Proces poszukiwania procedury obsługi dochodzi do funkcji
main i tam jej również nie znajduje. W tej
sytuacji następuje wyjście z programu poprzez wywołanie
funkcji
terminate,
(z nagłówka
exception)
która wywołuje z kolei funkcję
abort
kończącą program.
Użytkownik może, za pomocą funkcji
set_terminate,
ustalić inną, przez siebie
napisaną funkcję (bezrezultatową i bezparametrową) do
pełnienia roli funkcji
terminate. Tak czy owak,
nie może z niej być powrotu: program musi się skończyć,
ewentualnie po wykonaniu pewnych czynności porządkujących
lub informacyjnych określonych w funkcji
zastępującej
terminate.
W poniższym programie podstawiamy funkcję
termin zamiast
domyślnej
terminate (linia 18):
Wyszukiwarka
Podobne podstrony:
node136node132node138node132node136 YYN3RGJTIUYB5B7V76SG2CWOJ3Z3Q2BSSAGQGHInode130node13 EB3ZCAH7SPEEN2CTCJNWLAAPHAK7SBN34IUXSNYnode138 MPOLWBY7F5JRTBXYS57QFRPMNJNRLEKA6WXG3SAnode136 1node13node134node136 WDIY3HIN7ZG3NQWBCNN3XXBKEQZUQYN6VJDWQNAnode132Node13 Htmnode131więcej podobnych podstron