Miskolci Egyetem Általános Informatikai Tanszák
Kivételkezelés a C++ nyelvben Bevezetés Ficsor Lajos Miskolci Egyetem Általános Informatikai Tanszék Ficsor Lajos
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! Ficsor Lajos
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
Ficsor Lajos
Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
3
CBEV/ 1
Miskolci Egyetem Általános Informatikai Tanszák
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 ( ... ) Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
4
CPP9 /
5
Egyszerÿ példa 1. try { //utasítások char* szoveg = new char[200]; if ( szoveg == 0 ) throw "nincs memória"; //további utasítások } Ficsor Lajos
Kivételkezelés a C++ nyelvben
Egyszerÿ példa 2. catch ( char* uzenet ) { cout << uzenet << '\n'; //további utasítások az adott //állapot (most hiba) lekezelésére }
Ficsor Lajos
Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
6
CBEV/ 2
Miskolci Egyetem Általános Informatikai Tanszák
Mÿködés 1. • az elsÿ 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
Ficsor Lajos
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 • a catch 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 Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
8
Egymásba ágyazott kivételkezel k • A try blokkok egymásba ágyazhat explicit, vagy implicit módon (pl. függvényhívás) • A catch 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. Ficsor Lajos
Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
9
CBEV/ 3
Miskolci Egyetem Általános Informatikai Tanszák
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 Ficsor Lajos
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. Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
11
CPP9 /
12
class AllocError { int meret; public: AllocError(int m) {meret = m;} void uzenet(void) { cerr << meret << "byte lefoglalasa sikertelen" << "\n"; } }; Ficsor Lajos
Ficsor Lajos
Kivételkezelés a C++ nyelvben
CBEV/ 4
Miskolci Egyetem Általános Informatikai Tanszák
class Vektor { int n; int* p; public: class Range; Vektor(int hatar); int& operator[] (int i); }; Ficsor Lajos
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";} }; Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
14
CPP9 /
15
Vektor::Vektor(int hatar) { n = hatar; p = new int[n]; if (p == 0) throw AllocError(n*sizeof(int)); } Ficsor Lajos
Ficsor Lajos
Kivételkezelés a C++ nyelvben
CBEV/ 5
Miskolci Egyetem Általános Informatikai Tanszák
int& Vektor::operator[] (int i) { if (i >= 0 && i < n) return p[i]; throw Range(i); }
Ficsor Lajos
Kivételkezelés a C++ nyelvben
CPP9 /
16
CPP9 /
17
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; } Ficsor Lajos
Ficsor Lajos
Kivételkezelés a C++ nyelvben
CBEV/ 6