Różnice między wybraną wersją a wersją aktualną.
Both sides previous revision Previous revision | Last revision Both sides next revision | ||
opis_wyjatkow_w_bibliotece_standardowej [2008/12/11 22:59] verkaufo |
opis_wyjatkow_w_bibliotece_standardowej [2008/12/11 23:53] verkaufo dodanie kodu |
||
---|---|---|---|
Linia 88: | Linia 88: | ||
|bad_typeid | rzucany przez ''**typeid**'' | | |bad_typeid | rzucany przez ''**typeid**'' | | ||
|ios_base::failure | rzucany przez funkcje z biblioteki ''**<iostream>**'' | | |ios_base::failure | rzucany przez funkcje z biblioteki ''**<iostream>**'' | | ||
+ | ====== PRZYKŁAD ====== | ||
+ | <code c++> | ||
+ | /* | ||
+ | * Weronika Trybek I1ISI | ||
+ | * Zad. 5 Opis wyjątków w bibliotece standardowej. | ||
+ | */ | ||
+ | |||
+ | #include <iostream> | ||
+ | using namespace std; | ||
+ | |||
+ | /* | ||
+ | * Klasa Sensor oraz klasa SmokeDetector po niej dziedzicząca, | ||
+ | * to proste klasy, posiadające konstruktory i destruktory wyświetlające tekst | ||
+ | * w celu łatwiejszego zobrazowania mechanizmu obsługi wyjątków. | ||
+ | */ | ||
+ | class Sensor | ||
+ | { | ||
+ | protected: | ||
+ | int number_; | ||
+ | char* text_; | ||
+ | bool alarm_; | ||
+ | public: | ||
+ | Sensor() : number_(0), text_("Zwykly Czujnik"), alarm_(false) | ||
+ | { | ||
+ | cout << " Konstruktor domyslny Czujnika " << number_ << endl; | ||
+ | } | ||
+ | Sensor(int n, char* t) : number_(n), text_(t), alarm_(false) | ||
+ | { | ||
+ | cout << " Konstruktor Czujnika, "; | ||
+ | } | ||
+ | Sensor(const Sensor& s) | ||
+ | { | ||
+ | number_ = s.number_ + 1; | ||
+ | text_ = s.text_; | ||
+ | alarm_ = s.alarm_; | ||
+ | cout << " Konstruktor kopiujacy Czujnika " << s.number_; | ||
+ | if( text_ == "Zwykly Czujnik" ) | ||
+ | cout << ", powstaje " << number_ << endl; | ||
+ | else | ||
+ | cout << ", "; | ||
+ | } | ||
+ | virtual ~Sensor() | ||
+ | { | ||
+ | cout << " Destruktor Czujnika " << number_ << endl; | ||
+ | } | ||
+ | virtual void alarmOn() | ||
+ | { | ||
+ | alarm_ = true; | ||
+ | throw *this; | ||
+ | } | ||
+ | void alarmOff() | ||
+ | { | ||
+ | alarm_ = false; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | class SmokeDetector : public Sensor | ||
+ | { | ||
+ | static int counter_; | ||
+ | public: | ||
+ | SmokeDetector() : Sensor(++counter_, "Czujnik Dymu") | ||
+ | { | ||
+ | cout << "Czujnika Dymu " << number_ << endl; | ||
+ | } | ||
+ | SmokeDetector(const SmokeDetector& m) : Sensor(m) | ||
+ | { | ||
+ | ++counter_; | ||
+ | number_ = counter_; | ||
+ | cout << "Czujnika Dymu, powstaje " << number_ << endl; | ||
+ | } | ||
+ | ~SmokeDetector() | ||
+ | { | ||
+ | --counter_; | ||
+ | cout << " Destruktor Czujnika Dymu " << number_; | ||
+ | } | ||
+ | void alarmOn() | ||
+ | { | ||
+ | alarm_ = true; | ||
+ | throw *this; | ||
+ | } | ||
+ | }; | ||
+ | int SmokeDetector::counter_ = 0; | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | cout << "\n\n***Obsluga wyjatku, bez referencji do obiektu w argumencie catch***\n\n"; | ||
+ | try | ||
+ | { | ||
+ | Sensor sensor; // wywołanie konstruktora domyślnego Sensor (0) | ||
+ | sensor.alarmOn(); // throw sensor; -> wywołanie konstruktora kopiującego Sensor (1) | ||
+ | cout << "Jestem tutaj!\n"; // tekst ten nigdy nie będzie wyświetlony, bo sterowanie przechodzi do bloku catch | ||
+ | } // sporządzenie kopii statycznej dla catch -> wywołanie konstruktora kopiującego Sensor (2) | ||
+ | // odwikłanie stosu -> wywołanie destruktora Sensor (0) | ||
+ | catch(Sensor s) | ||
+ | { | ||
+ | cout << "catch(Sensor s)\n"; | ||
+ | } // koniec bloku catch -> wywołanie destruktora Sensor (2) i (1) | ||
+ | | ||
+ | cout << "\n\n***Obsluga wyjatku, z referencja do obiektu w argumencie catch***\n\n"; | ||
+ | try | ||
+ | { | ||
+ | Sensor sensor; // wywołanie konstruktora domyślnego Sensor (0) | ||
+ | sensor.alarmOn(); // throw sensor; -> wywołanie konstruktora kopiującego Sensor (1) | ||
+ | } // odwikłanie stosu -> wywołanie destruktora Sensor (0) | ||
+ | catch(Sensor& s) // wybrany catch | ||
+ | { | ||
+ | cout << "catch(Sensor& s)\n"; | ||
+ | } // koniec bloku catch -> wywołanie destruktora Sensor (1) | ||
+ | catch(...) // nie wchodzi tu juz, bo wyjątek został obsłuzony przez wczesniejszy catch | ||
+ | { | ||
+ | cout << "catch(...)\n"; | ||
+ | } | ||
+ | | ||
+ | cout << "\n\n***Obsluga wyjatku, dziedziczenie oraz zagniezdzone bloki try i catch***\n\n"; | ||
+ | try | ||
+ | { // zewnetrzny try | ||
+ | try // wewnetrzny try | ||
+ | { | ||
+ | SmokeDetector smokeDet; // wywołanie konstruktora Sensor (1) oraz SmokeDetector (1) | ||
+ | SmokeDetector smokeDet2; // wywołanie konstruktora Sensor (2) oraz SmokeDetector (2) | ||
+ | smokeDet.alarmOn(); // throw SmokeDetector;-> wywołanie konstruktora kopiującego Sensor (3) i SmokeDetector (3) | ||
+ | } // odwikłanie stosu -> wywołanie destruktorów SmokeDetector (2), Sensor (2) oraz SmokeDetector (1), Sensor (1) | ||
+ | catch(Sensor& s) // wybrany catch | ||
+ | { | ||
+ | cout << "catch(Sensor& s)\n"; | ||
+ | throw; // dalsze rzucenie tego samego obiektu | ||
+ | } // koniec bloku catch -> nie wywołany jest destruktor SmokeDetector, bo obiekt rzucony dalej | ||
+ | catch(SmokeDetector& s) // nie wchodzi tu juz, mimo iż dopasowanie byłoby lepsze, | ||
+ | { // bo wyjatek zostal obsluzony przez wczesniejszy blok catch | ||
+ | cout << "catch(MotionSensor& s)\n"; | ||
+ | } | ||
+ | } | ||
+ | catch(SmokeDetector& s) // wybrany catch, bo wyjątek został rzucony ponownie | ||
+ | { | ||
+ | cout << "zewnetrzny catch(MotionSensor& s)\n"; | ||
+ | } // koniec bloku catch -> wywołanie destruktora SmokeDetector, Sensor (2) | ||
+ | | ||
+ | cout << "\n\n***Obsluga wyjatku, odwiklanie stosu sprzata tylko to, co zostalo \n utworzone na stosie," | ||
+ | << " nie usuwa obiektow utworzonych za pomoca new***\n\n"; | ||
+ | try | ||
+ | { | ||
+ | Sensor* sensor = new Sensor; // wywołanie konstruktora Sensor (0) | ||
+ | sensor->alarmOn(); // throw sensor; -> wywołanie konstruktora kopiującego Sensor nr 1 | ||
+ | SmokeDetector smokeDet; // ten obiekt nigdy nie bedzie utworzony | ||
+ | } // odwikłanie stosu -> wywołanie destruktora wskaznika na Sensor (0), ale sam Sensor (0) nie zostaje usuniety | ||
+ | catch(Sensor& s) | ||
+ | { | ||
+ | cout << "catch(Sensor& s)\n"; | ||
+ | } // koniec bloku catch -> wywołanie destruktora Sensor (1) | ||
+ | catch(...) | ||
+ | { | ||
+ | cout << "catch(...)\n"; | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
--- //[[verkaufo@gmail.com|Weronika Trybek]] 2008/12/11 22:50// | --- //[[verkaufo@gmail.com|Weronika Trybek]] 2008/12/11 22:50// | ||
- | {{:exception.cpp|}} | + |