1 / 16

C++ programozási nyelv Gyakorlat - 11. hét

Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2004. december. C++ programozási nyelv Gyakorlat - 11. hét. Tartalomjegyzék. Mit nevezünk kivételkezelésnek? Miért fontos ez? Mi a megoldás? Miért nem jó ez a megoldás? A kivételkezelés ötlete

ashley
Download Presentation

C++ programozási nyelv Gyakorlat - 11. hét

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor 2004. december C++ programozási nyelvGyakorlat - 11. hét

  2. Tartalomjegyzék • Mit nevezünk kivételkezelésnek? • Miért fontos ez? • Mi a megoldás? • Miért nem jó ez a megoldás? • A kivételkezelés ötlete • Kivétel keletkezése • A kivétel addig terjed, míg el nem kapjuk • Kivételt szándékosan is létre lehet hozni ('dobás') • A kivétel típusát meg tudjuk állapítani • A kivétel értékét is használhatjuk • A függvényeket ugyanúgy hagyja el a program, mint normális esetben • A kivétel továbbdobható • Transzformálás 1: Elkapás után másik kivétel dobható tovább • Transzformálás 2: Elkapás után hibakódot adunk vissza

  3. Mit nevezünk kivételkezelésnek? • Szűkebb értelemben: • A programban fellépő futásidejű hibák kezelését. • Tágabb értelemben: • A program normál logikájához képest különleges, attól eltérő helyzetek kezelését. • Ez azt is jelenti, hogy abszolút nem hibás esetek kezelését is megoldhatjuk a kivételkezelés mechanizmusával. • A végső cél: • Teljes egészében kezünkben tartsuk a program működését, minden helyzetben a szándékaink szerint reagáljon a program. Soha ne forduljon elő olyan eset, amikor a program úgy fejeződik be, hogy valamit "elvarratlanul" hagyott.

  4. Miért fontos ez? • Milyen problémákat okozhat egy rendkívüli program leállás? • adatvesztés: • nyitva maradt fájlok • még el nem mentett, berögzített adat. A felhasználó begépelt 5 oldalnyi szöveget, amikor a program "elszáll", vagy hibajelzéssel leáll. • időveszteség: • egy 5 órája futó kalkuláció a végeredmény elkészülte és a részeredmények elmentése nélkül hibajelzéssel leáll. • erőforrások fogvatartása • a program futása során lefoglal bizonyos erőforrásokat (fájlok, adatbázis rekordok), ezeket a futás végén szabadítaná fel.

  5. Mi a megoldás? • A programot fel kell készíteni minden eshetőségre. • Például: Az előző program hibakezeléssel: program { if (fuggveny1() = OK) { if (fuggveny2() = OK) { if (fuggveny3() = OK) { // minden rendben } else { // hibakezelés3 } } else { // hibakezelés2 } } else { // hibakezelés1 } } Egy egyszerű program: program { fuggveny1(); fuggveny2(); fuggveny3(); } Miért nem jó ez?

  6. Miért nem jó ez a megoldás? • A hibakezelés elrejti, széttördeli az eredeti programlogikát: • nehezen olvasható kód • nehezen javítható, módosítható a kód • A hibakezelő programrésznek nincs információja a hiba jellegéről, okáról • Nagyobb programok esetén ez a megoldás kivitelezhetetlen, sőt... • hiba bekövetkezhet a hibakezelő programrészben is, ezért oda is kellene ellenőrzés, ...

  7. A kivételkezelés ötlete • Válasszuk szét az eredeti programlogikát és a kivételes helyzetek (hibaállapotok) kezelését • A kivételkezelő kapjon információt a hiba típusáról, helyéről és egyéb körülményeiről • A kivételkezelő legyen képes visszatérni az eredeti programlogikához, ha a hiba jellege ezt lehetővé teszi. • Legyen lehetőség garantálni a program és minden részprogram korrekt befejeződését bármilyen körülmények fennállása esetén (fájlok bezárása, erőforrások felszabadítása, stb.)

  8. Kivétel keletkezése int main() // except_bem1.cpp { int x,y; try{ y = 0; x = 1 / y; } catch(...){ // minden kivételt elkapunk printf("Kivetel dobasa tortent\n"); } return 0; } • try nélkül, debug indításával: a hibaüzenet az, hogy lekezeletlen kivételt kapott el a futtató rendszer, mégpedig a nullával osztáshoz tartozót. • A kivételt létrehozhatja a futtató rendszer, vagy mi magunk.

  9. A kivétel addig terjed, míg el nem kapjuk int main() { try{ KiveteltDob(); } catch(...){ // minden kivételt elkapunk printf("Kivetel dobasa tortent\n"); } try{ F(); } catch(...){ // minden kivételt elkapunk printf("Kivetel dobasa tortent\n"); } return 0; } // except_bem2.cpp void KiveteltDob() { int x,y; y = 0; x = 1 / y; } void F() { KiveteltDob(); }

  10. Kivételt szándékosan is létre lehet hozni ('dobás') void Dob1(int X) { if(X == 0) throw 122; } // except_bem3.cpp void Dob2(int X) { if(X == 0) throw "Baj van!"; } int main() { try{ Dob1(0); } catch(...){ // minden kivételt elkapunk printf("Kivetel dobasa tortent\n"); } try{ Dob2(0); } catch(...){ // minden kivételt elkapunk printf("Kivetel dobasa tortent\n"); } return 0; } • Megjegyzés: Sztringet dobni nem nagyon érdemes, a gyakorlatban kevéssé használható (ld. később).

  11. A kivétel típusát meg tudjuk állapítani void Dob1(int X) { if(X == 0) throw 122; } // except_bem4.cpp void Dob2(int X) { if(X == 0) throw "Baj van!"; } int main() { try{ Dob1(0); } catch(int){ printf("int kivetel dobasa tortent\n"); } catch(...){ // minden egyéb kivételt elkapunk printf("Egyeb kivetel dobasa tortent\n"); } try{ Dob2(0); } catch(char*){ printf("char* kivetel dobasa tortent\n"); } catch(...){ // minden egyéb kivételt elkapunk printf("Egyeb kivetel dobasa tortent\n"); } return 0; }

  12. A kivétel értékét is használhatjuk void Dob1(int X) { if(X == 0) throw 122; } // except_bem5.cpp void Dob2(int X) { if(X == 0) throw "Baj van!"; } int main() { try{ Dob1(0); } catch(int k) { printf("int kivetel dobasa tortent: %d\n",k); } catch(...) { // minden egyéb kivételt elkapunk printf("Egyeb kivetel dobasa tortent\n"); } try{ Dob2(0); } catch(char* k) { printf("char* kivetel dobasa tortent: %s\n",k); } catch(...) { // minden egyéb kivételt elkapunk printf("Egyeb kivetel dobasa tortent\n"); } return 0; }

  13. A függvényeket ugyanúgy hagyja el a program, mint normális esetben class A{ public: A() { printf("A::A()\n"); } ~A() { printf("~A::A()\n"); } }; void f(int X) { A a; if(X == 1){ printf("Kivetelt dobok\n"); throw 1; } printf("Nem dobtam kivetelt\n"); } void main() { f(0); printf("-------\n"); try{ f(1); } catch(...) {} printf("Mindig lefut A::~A()!\n"); } • Persze ami nincs objektumba csomagolva, vagy dinamikus objektumban van, az nem záródik le! • Lásd except_bem7.cpp !

  14. A kivétel továbbdobható void F1() { throw 42; } // except_bem8.cpp void F2() { try{ F1(); } catch(int x){ printf("F2: elkaptam: %d\n",x); printf("Feldolgoztam, tovabbdobom\n"); throw; } } int main() { try{ F2(); } catch(int x){ printf("main: elkaptam: %d\n",x); } return 0; }

  15. Transzformálás 1: Elkapás után másik kivétel dobható tovább • Ez pl. arra használható, hogy a kapott sokféle kivétel információit felírjuk (log), majd kevés féle kivételt adunk tovább. A feldolgozás után már csak nagyvonalúbb leírásra van szükség, a részletek csak zavarnak. Ez a következő pontra is érvényes. #define VALAMI_NAGY_BAJ -1 void F1(int X) { if(X < -1000) throw "Nagy baj 1"; if(X < -100) throw "Nagy baj 2"; if(X < -10) throw "Nagy baj 3"; } void F2() { try{ F1(-777); } catch(char* x){ printf("F2: elkaptam: %s\n",x); printf("Feldolgoztam, tovabbdobom\n"); throw VALAMI_NAGY_BAJ; } } // except_bem9a.cpp int main() { try{ F2(); } catch(int x){ printf("main: elkaptam: %d\n",x); if(x == VALAMI_NAGY_BAJ) printf("Valami nagy baj tortent\n"); } return 0; }

  16. Transzformálás 2: Elkapás után hibakódot adunk vissza // except_bem9b.cpp int main() { int rc; rc = F2(); printf("main: F2 visszatero erteke: %d\n",rc); if(rc == VALAMI_NAGY_BAJ) printf("Valami nagy baj tortent\n"); return 0; } #define VALAMI_NAGY_BAJ -1 void F1(int X) { if(X < -1000) throw "Nagy baj 1"; if(X < -100) throw "Nagy baj 2"; if(X < -10) throw "Nagy baj 3"; } int F2() { try{ F1(-777); } catch(char* x){ printf("F2: elkaptam: %s\n",x); printf("Feldolgoztam\n"); return VALAMI_NAGY_BAJ; } return 0; }

More Related