Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 1 Programowanie Wizualno Obiektowe Zajęcia 5, część 1 Temat: Zadanie: Obsługa wyjątków. Program wyświetla na ekranie wynik z dzielenia dwóch liczb rzeczywistych. Podczas działania programu zaprezentowana jest obsługa sytuacji wyjątkowych. Rysunek 5.2. Postać interfejsu użytkownika dla programu 5_2
Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 2 1. Otwieramy nowa aplikację File>NewApplication 2. Zapisujemy projekt przy pomocy File>Save All w katalogu gdzie będzie kompilowany nasz projekt 3. Dodajemy odpowiednie komponenty w kolejności Komponent głównego menu TMainMenu. Komponenty z polami edycyjnymi TEdit Komponenty z etykietami TLabel Komponent paska statusu TStatusBar. Komponent z przyciskiem TButton 4. Do głównego menu dodać następujące opcje Koniec 5. Wyjście z programu zrealizować wykorzystując okienko dialogowe 6. Nazwać odpowiednie komponenty charakterystycznymi nazwami, a następnie w pliku nagłówkowym unit1.h zadeklarować zmienne wykorzystywane podczas dzielenia: private: // User declarations float wart_x, wart_y, wynik; 7. Obsłużyć zdarzenie naciśnięcia na przycisk i dzielenia dwóch liczb które zostały odczytane z pól edycyjnych void fastcall TForm1::BtnDzielenieClick(TObject *Sender) wart_x=strtofloat(this->edtwartoscx->text); wart_y=strtofloat(this->edtwartoscy->text); this->lblwynik->caption=floattostr(wynik); 8. Aby można było korzystać z obsługi wyjątków tak, żeby nie były wyświetlane dodatkowe błędy pochodzące od kompilatora, należy przed kompilacją wybrać opcję Tools->Debugger Options->Language Exceptions i odznaczyć pola Stop on Delphi Exceptions, oraz Stop on C++ Exceptions.
Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 3 9. Wyjątki - wstęp 9.1. Informacje podstawowe Wyjątki - są to sytuacje/zdarzenia występujące podczas wykonywania programu, nad którymi program nie ma kontroli i/albo wymagają specjalnego obsłużenia. Ich obsługa przydatna jest podczas pracy z programem, oraz podczas pisania aplikacji. Przykładowe sytuacje wyjątkowe standardowo obsługiwane przez Borland C++ VCL to dzielenie przez 0, obsługa złych formatów plików, przekroczenie dostępnych wartości. Obsługa wyjątków - przewidywanie w programie sytuacji wyjątkowych i reagowanie na nie. UWAGA: Korzystanie z wyjątków powinno być zarezerwowane dla błędów krytycznych. Wyjątek powinien być generowany wtedy, gdy błędna sytuacja jest na tyle niebezpieczna, że może utrudnić dalsze funkcjonowanie programu. Większości błędów wykonania można zapobiec, sprawdzając zawczasu poprawność danych, użyte parametry itp. 9.2 Bloki obsługi wyjątków (ang. try statements) a) try w połączeniu z catch try <instrukcje programu> catch (<typ wyjątku>) <obsługa wyjątku> catch (<typ wyjątku>) <obsługa wyjątku> ; catch () <obsługa pozostałych wyjatków> ; end; W tym przypadku wykonywane są <instrukcje programu>; jeżeli wykonywanie jednej z tych instrukcji spowoduje wystąpienie wyjątku wykonywana jest sekcja rozpoczynająca się od słowa catch. Dyrektywy (<typ wyjątku>) w sekcji catch służą do zróżnicowanej obsługi poszczególnych typów wyjątków.
Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 4 Wybrane przypadki przechwytywania wyjątków a) z obsługą wyjątków, bez ich wyszczególnienia try catch() <obsługa wyjątków> ; try wart_x=strtofloat(this->edtwartoscx->text); wart_y=strtofloat(this->edtwartoscy->text); catch() Application->MessageBox("Błąd","Wystąpił błąd",mb_ok); ; b) z obsługą wyszczególnionego wyjątku try catch(<wyjątek>) <obsługa wyjątku> (wybrany wyjątek to błąd konwersji danych w polu edycyjnym) try //obsługa dowolnego wyjątku z listy wszytkich wyjątków wart_x=strtofloat(this->edtwartoscx->text); catch(econverterror &ConvErr) Application->MessageBox("Wystąpił błąd konwersji znakow","błąd",mb_ok); c) z obsługą kilku wyszczególnionych wyjątków
Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 5 try catch(<wyjątek 1>) <obsługa wyjątku 1> catch(<wyjątek 2>) <obsługa wyjątku 2> ; (wybrane wyjątki to błąd konwersji danych w polu edycyjnym oraz błąd dzielenia przez 0) try wart_y=strtofloat(this->edtwartoscy->text); catch(econverterror &ConvErr) //obsługa pierwszego wyjątku Application->MessageBox("Wystąpił błąd konwersji znakow","błąd",mb_ok); this->lblwynik->caption="(błąd)"; catch(ezerodivide &DivZeroErr); //obsługa drugiego wyjątku Application->MessageBox("Wystąpił błąd dzielenia przez zero","błąd",mb_ok); this->lblwynik->caption="(błąd)"; ; d) z wykorzystaniem informacji dostępnych w przechwyconym wyjątku try catch(typ_wyjątku &nazwa_wyjątku) <obsługa wyjątku, wykorzystanie danych z &nazwa_wyjatku> W tym przypadku możliwe jest wykorzystanie informacji dostępnych w wyjątku. W tym celu wykorzystuje się stworzony wskaźnik do obiektu wyjątku utworzony przy pomocy dyrektywy catch(typ_wyjątku &nazwa_wyjątku). Można wtedy w instrukcjach obsługujących wyjątek wykorzystać informacje z własności wyjątku. (wybrany wyjątek to błąd dzielenia przez 0) try
Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 6 catch(ezerodivide &DivZeroErr) this->statusbar1->panels->items[0]->text=divzeroerr.message; Application->MessageBox("Wystąpił błąd dzielenia przez zero","błąd",mb_ok); e) obsługa wyjątków z wykorzystaniem dyrektywy finally W tym przypadku wykonywane są, po ich zakończeniu albo przerwaniu z powodu wyjątku wykonywane są <instrukcje końcowe> zostaną one wykonane zawsze, niezależnie od tego, w jaki sposób zakończyło się wykonywanie <instrukcji> i jakie zostały przechwycone wyjątki. Pozwala to na zakończenie pewnych instrukcji lub ich wykonanie bez względu na występujące błędy. try finally <instrukcje końcowe> 9.3 Generowanie własnych wyjątków (Temat zaawansowany, zwykle wykorzystywane przy pisaniu własnych komponentów)
Programowanie Wizualno Obiektowe - zajęcia 5 (PWO_BCPP_5_1) 7 9.4. Wyjątki dostępne dla komponentów VCL (C++ Help) EComponentError EConvertError EDatabaseError EDBEditError EDivByZero EExternalException EInOutError EIntOverflow EInvalidCast EInvalidGraphic EInvalidOperation EInvalidPointer EMenuError EOleCtrlError EOleError EPrinterError EPropertyError ERangeError ERegistryException EZeroDivide Sygnalizuje nieudaną próbę rejestracji lub zmiany nazwy komponentu Sygnalizuje błąd konwersji zmiennej typu łańcuch znaków (string) lub obiektu Sygnalizuje błąd podczas dostępu do bazy danych Przechwytuje dane nie zgadzające się z określoną maską (bazy danych). Sygnalizuje błędy dzielenia przez zero liczb całkowitych. Sygnalizuje nieokreślony wyjątek. Sygnalizuje błąd wejścia/wyjścia Sygnalizuje obliczenia na liczbach całkowitych, których wynik jest zbyt duży (przekracza zaalokowana pamięć) Sygnalizuje błędną wielkość znaków Sygnalizuje próbę pracy z nierozpoznawalnym formatem pliku graficznego Sygnalizuje błędną operację z wykorzystaniem komponentu Sygnalizuje błędną operację na wskaźniku. Sygnalizuje problem z elementem menu. Sygnalizuje problem z odnośnikiem do kontrolki ActiveX. Sygnalizuje błędy OLE Sygnalizuje błędy związane z drukowaniem. Sygnalizuje nieudane nadanie wartości jakiejś własności obiektu Sygnalizuje przekroczenie dopuszczalnego zakresu dla liczby całkowitej. Sygnalizuje błędy rejestru systemowego Sygnalizuje błędy dzielenia przez zero liczb rzeczywistych