To jest stara wersja strony!
Obsługa wyjątków zapewnia reakcję na nietypowe zdarzenia w programie, a w szczególności sytuacje błędne. Przekazuje ona sterowanie do specjalnych procedur obsługi sytuacji wyjątkowych zwanych handlerami. Podstawowymi słowami kluczowymi dotyczącymi zajmowania się wyjątkami są:
try, throw, catch
W bloku try
znajdują się instrukcje, które mogą rzucać wyjątki. Kiedy nastąpi sytuacja wyjątkowa w jednej z instrukcji znajdujących się w tym bloku, sterowanie zostaje przekazane do odpowiedniego bloku catch
. Za blokiem try
musi pojawić się co najmniej jeden blok catch
, w przeciwnym wypadku następuje błąd kompilacji.
Służy do rzucania obiektów w sytuacji wyjątkowej. Działanie funkcji, w której nastąpi instrukcja throw
, zostaje natychmiast przerwane, a rzucony obiekt zostaje natychmiast przekazany do bloku catch
jako argument, gdzie zostaje obsłużona sytuacja wyjątkowa.
Blok ten łapie obiekty konkretnego typu rzucone w bloku try
. Jeśli typ rzuconego obiektu zgadza się z typem argumentu catch
następuje obsługa sytuacji wyjątkowej przez ten jeden blok catch
Kolejność bloków catch
ma znaczenie, ponieważ kompilator wybiera PIERWSZY blok, który może złapać rzucony wyjątek, nawet jeśli kolejne bloki catch
pasują lepiej. Każdy z bloków catch
znajdujący się pod jednym blokiem try
musi przyjmować inny argument.
catch(…)
- może łapać obiekty wszystkich typów.
try { throw 1; } catch(int i) { cout << "Wyjątek! Nr " << i << endl; }
Po rzuceniu wyjątku i obsłużeniu go w bloku catch
nie następuje powrót do uprzednio wykonywanej funkcji, gdzie rzucono wyjątek za pomocą throw
. Wykonywane są instrukcje znajdujące się po sekwencji bloków try
i catch
.
W bloku catch
możliwe jest rzucenie obiektu ‘dalej’, do dalszej obsługi za pomocą throw;
bez argumentów.
Podczas deklaracji funkcji można ograniczyć typy wyjątków, które rzuca dana funkcja poprzez dodanie throw (typ)
:
int funkcja(int i) throw (int); //funkcja rzuca wyjątki typu int int funkcja(int i) throw' (); //funkcja nie może rzucać żadnych wyjątków int funkcja(int i); //funkcja rzuca wyjątki dowolnego typu
Jeśli w bloku try
powstały obiekty automatyczne, to w momencie, gdy wyjątek jest rzucany i sterowanie przechodzi do bloku catch
, następuje odwikłanie stosu. Jest to usunięcie wszystkich obiektów automatycznych, które zdarzyły powstać w bloku try
w kolejności odwrotnej do tworzenia.
try { Object a; Object b; Object c; throw 1; Object d; } // odwikłanie stosu: uruchomienie destruktora klasy Object, najpierw dla obiektu c, potem b, na końcu a, // nie zostanie on uruchomiony dla obiektu d, bo nie został on jeszcze utworzony. catch (int i) { cout << "Wyjątek! Nr " << i << endl; }
Funkcja ta kończy program zamykając wszystkie pliki i opróżniając wszystkie bufory.
Funkcja brutalnie kończy program, ‘nie sprzątając’ po sobie.
Gdy żaden z bloków catch
nie potrafi obsłużyć wyjątku, wywoływana jest funkcja terminate()
. Funkcja ta zostanie również wywołana przy odwikłaniu stosu, gdy destruktor obiektu rzuca nowy wyjątek lub gdy pomiędzy rzuceniem obiektu, a złapaniem go w bloku catch
nastąpi wywołanie konstruktora kopiującego, który próbuje rzucić nowym wyjątkiem. terminate()
wywołuje funkcję abort()
, aby zmienić to wywołanie na funkcję wybraną przez programistę można to zrobić za pomocą funkcji (void(*wsk)()) set_terminate(void (*wsk)())
.
Gdy funkcja deklaruje konkretne typy rzucanych wyjątków, a rzuca wyjątek innego typu, wyjątek ten nie może zostać obsłużony. Wywoływana jest wtedy funkcja unexpected()
, która domyślnie na koniec wywołuje funkcję terminate()
. Funkcją (void (*wsk)()) set_unexpected(void (*wsk)())
można zmienić wykonywanie terminate()
, na rzecz wykonania funkcji wybranej przez programistę.
Biblioteka standardowa dostarcza klasę bazową dla obiektów, które są rzucane jako wyjątki. Zdefiniowana jest ona w <exception>
(przestrzeń nazw - std
).
wyjątek | opis |
---|---|
bad_alloc | rzucany przez new przy nieudanej alokacji pamięci |
bad_cast | rzucany przez dynamic_cast |
bad_exception | rzucany gdy wyjątek nie pasuje do żadnego bloku catch |
bad_typeid | rzucany przez typeid |
ios_base::failure | rzucany przez funkcje z biblioteki <iostream> |
— Weronika Trybek 2008/12/11 22:50 exception.cpp