Języki i techniki programowania
Ćwiczenia 5 Obsługa błędów
Autor: Marcin Orchel Sposoby obsługi błędów
1. funkcja przerywa działanie programu, gdy napotka problem
2. przekazywanie kodu błędu, np: wartości int do funkcji wywołującej - kod błędu nie może być przekazany w przypadku konstruktora 3. zastosowanie wyjątków
Wyjątki
Wyjątek to pewne zdarzenie.
Możemy rzucać pewną klasę reprezentującą błąd.
Błędy można grupować w hierarchie.
class Error {
public: virtual void showError() {
cout << "error" << endl;
} };
class DivisionError : public Error {
public: void showError() {
cout << "Division error" << endl;
} };
int main() {
try {
throw DivisionError();
}
catch(Error & error) {
error.showError();
}
catch(...) {
cout << "Unknown error" << endl;
} }
W powyższym przykładnie zostanie wywołana metoda showError() z klasy DivisionError.
Throw bez parametrów
Wywołanie throw bez parametrów spowoduje wyrzucenie wyjątku na zewnątrz. A więc obsługa danego wyjątku może być kontynuowana.
catch(...)
Catch(...) oznacza łapanie dowolnego wyjątku.
Przykład wyrzucenia wyjątku w konstruktorze
Rzucamy wyjątek w klasie Triangle, jeśli parametry nie spełniają warunków trójkąta:
Triangle(int a, int b, int c) {
if (a >= b + c || b >= a + c || c >= a + b) {
throw InequalityException();
}
this->a = a;
this->b = b;
this->c = c;
}
Łapanie wyjątków
Wyjątki najlepiej łapać przez referencję.
Wyjątki mogą być obsługiwane w metodzie, w której są wyrzucane, lub mogą być przekazywane wyżej.
Różnice między wyjątkami w C++ i Javie.
- w Javie wszystkie wyjątki muszą dziedziczyć po klasie Throwable
- w Javie rozróżniamy checked exceptions i unchecked exceptions, w C++ nie ma takiego rozróżnienia: checked exceptions muszą być obsłużone, unchecked exceptions nie powinny być obsługiwane, są to zazwyczaj błędy programistyczne, unchecked exceptions wyjątki dziedziczone po RuntimeException()
- w Javie w przypadku checked exceptions musimy zadeklarowac rzucane wyjatki dalej przy definicji metody slowo kluczowe throws, jest to sprawdzane podczas kompilacji, w C++ nie ma takiej deklaracji
- w Javie dostępny jest blok finally, który sie wykona nawet po uruchomieniu return, w C++
nie ma tego bloku, za to są destruktory
- w C++ jest dodatkowa składnia catch(...), która pozwala na łapanie dowolnych wyjątków, w Javie nie ma takiej skladni.
Zadania
Zadanie podstawowe
- wyrzucanie wyjątków w zadaniu podstawowym zestawu 4 z implementacją listy ze wzorcami:
- z funkcji addElement(int index) w sytuacji gdy chcemy dodać obiekt na miejsce poza listą - z funkcji removeElement(T element), w sytuacji gdy dany element nie istnieje, lub gdy lista jest pusta
- z funkcji swapElements(int index1, int index2), jeśli indeksy są spoza listy lub są równe - z funkcji getElement(int index), jeśli indeks jest spoza listy
- zdefiniować konstruktor do listy z parametrem maksymalna ilość pól, podczas wywołania funkcji addElement(int index) rzucać odpowiedni wyjątek, gdy rozmiar listy przekroczy powyższe ograniczenie
- zdefiniować konstruktor do listy, który jako parametr otrzymuje tablicę elementów, w konstruktorze rzucać wyjątek, jeśli tablica jest pusta
- wszystkie rzucane wyjątki obsłużyć w klasie Figures, która przechowuje zdefiniowaną powyżej listę figur
Uwaga:
Każdy wyjątek rzuca osobną klasę zdefiniowaną specjalnie dla tego wyjątku. Np. definiujemy klasę IndexOutOfBoundException.
Zadanie dodatkowe 1
- napisać klasę FileReader, która czyta pliki tekstowe i zapisuje linie do listy stringów.
Metoda read rzuca wyjątki, gdy plik jest pusty, gdy plik nie istnieje, gdy plik jest w danym momencie używany przez inny program.
Napisz program zewnętrzny, który czyta listę trójkątów z pliku i obsługuje te wyjątki.
Należy zwrócić uwagę na zamykanie czytanego pliku również przy rzucanych wyjątkach.
Umieścić w drugiej wersji zamykanie pliku w destruktorze klasy FileReader.
- napisać klasę FileWriter, która zapisuje podaną listę trójkątów do pliku. Metoda write rzuca podobne wyjątki jak metoda read w klasie FileReader.
Dla każdego wyjątku stworzyć osobną klasę.
Zadanie dodatkowe 2
- napisac klasę BinaryTree, ktora implementuje drzewo binarne. Napisać metody
umożliwiające dodawanie nowych elementów do drzewa, usuwanie elementów z drzewa oraz wyszukiwanie elementów w drzewie. Rzucać wyjątki podobne jak przy liście, oraz gdy dany element nie został znaleziony w drzewie.