Kivételkezelés a C++ nyelvben Bevezetés Miskolci Egyetem Általános Informatikai Tanszék Kivételkezelés a C++ nyelvben CPP9 / 1 Hagyományos hibakezelés Függvény visszatérési értéke (paramétere) hátrányai: azonosítás hibaérték / valódi érték hívási hierarchia! globális változó C++: hibastátusz adattag és visszaadó függvény Ellenÿrzés nehézkes, sok helyre kell beiktatni. Kód áttekinthetÿségét rontja! Kivételkezelés a C++ nyelvben CPP9 / 2 Kivétel fogalma Nem azonos az operációs rendszer exeption fogalmával. Kivétel az, amit programozó annak tekint. A C++ szemléletében a kivétel egy objektum, ami a kivétel bekövetkezésekor jön létre. Kivétel kiváltása: throw Kivételkezelés a C++ nyelvben CPP9 / 3 CBEV/ 1
A kivételek kezelése try blokk: a "védett" programrészt fogja közre. try utasítások catch blokk(ok): a keletkezett kivételek lekezelése catch (típus paraméter) utasítások vagy catch ( típus ) vagy catch (... ) Kivételkezelés a C++ nyelvben CPP9 / 4 try //utasítások Egyszerÿ példa 1. char* szoveg = new char[200]; if ( szoveg == 0 ) throw "nincs memória"; //további utasítások Kivételkezelés a C++ nyelvben CPP9 / 5 Egyszerÿ példa 2. catch ( char* uzenet ) cout << uzenet << '\n'; //további utasítások az adott //állapot (most hiba) lekezelésére Kivételkezelés a C++ nyelvben CPP9 / 6 CBEV/ 2
Mÿködés 1. azelsÿ throw utasítással befejezÿdik a try blokk végrehajtása kilép a blokkból a vezérlés, rendcsinálással verem visszaállítása lokális objektumokmegszüntetése létrejön a throw utasításban megjelölt objektum egy példánya Kivételkezelés a C++ nyelvben CPP9 / 7 Mÿködés 2. megkeresi a program azt az elsÿ catch blokkot, amely a kivétel objektumra illeszkedik (az illeszkedés fogalmát késÿbb pontosítjuk) végrehajtja a blokk utasításait acatch blokk végrehajtása után az utolsó catch blokk utáni elsÿ utasításra kerül a vezérlés ha kivétel keletkezett, de egy catch blokk sem illeszkedett, a terminate függvény hívódik meg, ami leállítja a programot Kivételkezelés a C++ nyelvben CPP9 / 8 Egymásba ágyazott kivételkezel k Atry blokkok egymásba ágyazhat explicit, vagy implicit módon (pl. függvényhívás) Acatch blokkok keresése (és a verem visszagombolyítása) "belülrÿl kifelé" történik. Ha verem visszagombolyítás közben újabb kivétel keletkezik, a terminate függvény hívódik meg A kivétel lekezelése (vagy annak egy része) továbbhárítható a feljebb álló szintekre a paraméter nélküli throw utasítással. Kivételkezelés a C++ nyelvben CPP9 / 9 CBEV/ 3
Leszármaztatott kivétel osztályok Mivel a kivétel egy objektum, kivétel osztályok között lehetséges leszármazási hierachiát létrehozni, és ezzel csoportosítani a kivételeket. Egy E kivételobjektum illeszkedik a cath (H) blokkra, ha H és E típusa azonos H egy egyértelm bázisosztálya E-nek H és E pointerek és alaptípusukra a fenti érvényes H egy referencia, és a hivatkozott típusra az elsÿ két pont valamelyike érvényes Kivételkezelés a C++ nyelvben CPP9 / 10 Általános catch blokk Formája: catch (... ) Erre a blokkra bármilyen kivétel objektum illeszkedik, tehát logikusan csak az utolsó lehet a blokkok sorában. Használhatjuk arra, hogy minden egyéb, speciális kezelés nem igénylõ kivételt itt kezeljünk le. Gyakran végzÿdik a kivétel továbbdobásával. Kivételkezelés a C++ nyelvben CPP9 / 11 class AllocError int meret; public: AllocError(int m) meret = m; void uzenet(void) cerr << meret << "byte lefoglalasa sikertelen" << "\n"; ; Kivételkezelés a C++ nyelvben CPP9 / 12 CBEV/ 4
class Vektor int n; int* p; public: class Range; Vektor(int hatar); int& operator[] (int i); ; Kivételkezelés a C++ nyelvben CPP9 / 13 class Vektor::Range int index; public: Range(void) index = 0;; Range (int i) index=i; void uzenet(void) cerr<< "Hibas index: " << index << "\n"; ; Kivételkezelés a C++ nyelvben CPP9 / 14 Vektor::Vektor(int hatar) n = hatar; p = new int[n]; if (p == 0) throw AllocError(n*sizeof(int)); Kivételkezelés a C++ nyelvben CPP9 / 15 CBEV/ 5
int& Vektor::operator[] (int i) if (i >= 0 && i < n) return p[i]; throw Range(i); Kivételkezelés a C++ nyelvben CPP9 / 16 int main(int argc, char* argv[]) try Vektor v(100); v[100] = 5; catch (AllocError error) error.uzenet(); catch (Vektor::Range r) r.uzenet(); return 0; Kivételkezelés a C++ nyelvben CPP9 / 17 CBEV/ 6