C++ kalboje išimtys yra vykdymo anomalijos arba neįprastos sąlygos, su kuriomis programa susiduria vykdydama. Šių išimčių tvarkymo procesas vadinamas išimčių tvarkymu. Naudojant išimčių tvarkymo mechanizmą, valdymas iš vienos programos dalies, kurioje įvyko išimtis, gali būti perkeltas į kitą kodo dalį.
Taigi iš esmės naudodami išimčių tvarkymą C++, galime tvarkyti išimtis, kad mūsų programa veiktų toliau.
shehzad poonawala
Kas yra C++ išimtis?
Išimtis yra netikėta problema, kuri iškyla vykdant programą, mūsų programa staiga nutrūksta dėl tam tikrų klaidų / problemų. Išimtis atsiranda programos vykdymo metu (vykdymo metu).
C++ išimčių tipai
C++ yra dviejų tipų išimtys
- Sinchroninis: Išimtys, kurios nutinka, kai kas nors negerai dėl įvesties duomenų klaidos arba kai programa nėra pritaikyta apdoroti esamo tipo duomenų, su kuriais ji dirba, pvz., skaičių padalijus iš nulio.
- Asinchroninis : išimtys, kurių programa negali kontroliuoti, pvz., disko gedimas, klaviatūros pertraukimai ir kt.
C++ pabandykite ir sugauti
C++ suteikia integruotą išimčių tvarkymo funkciją. Tai galima padaryti naudojant šiuos specializuotus raktinius žodžius: bandyti, gaudyti ir mesti, kiekvienas turi skirtingą paskirtį.
Try-catch sintaksė C++
try { // Code that might throw an exception throw SomeExceptionType('Error message'); } catch ( ExceptionName e1 ) { // catch block catches the exception that is thrown from try block }> 1. Pabandykite C++
Raktinis žodis try reiškia kodo bloką, kuris gali sukelti išimtį, esančią try bloko viduje. Po jo seka vienas ar daugiau gaudymo blokų. Jei įvyksta išimtis, pabandykite blokuoti tą išimtį.
2. sugauti C++
Catch teiginys reiškia kodo bloką, kuris vykdomas, kai iš trynimo bloko išmetama tam tikra išimtis. Išimties apdorojimo kodas parašytas gaudymo bloke.
3. mesti C++
Išimtį C++ galima išmesti naudojant raktinį žodį mesti. Kai programa susiduria su mesti teiginiu, ji nedelsdama nutraukia dabartinę funkciją ir pradeda rasti atitinkamą gaudymo bloką, kad būtų galima apdoroti išmestą išimtį.
Pastaba: Keli gaudymo teiginiai gali būti naudojami norint užfiksuoti įvairaus tipo išimtis, kurias meta trynimo blokas.
Bandymo ir gaudymo raktiniai žodžiai pateikiami poromis: Naudojame trynimo bloką tam, kad išbandytume tam tikrą kodą, o jei kodas padarys išimtį, tvarkysime jį savo gaudymo bloke.
Kodėl mums reikia Išimčių tvarkymas C++?
Toliau pateikiami pagrindiniai išimčių tvarkymo pranašumai, palyginti su tradiciniu klaidų apdorojimu:
- Klaidų tvarkymo kodo atskyrimas nuo įprasto kodo : Visada yra „jei-kita“ sąlygų tvarkyti tradicinių klaidų tvarkymo kodų klaidas. Šios sąlygos ir klaidų tvarkymo kodas susimaišo su įprastu srautu. Dėl to kodas tampa mažiau skaitomas ir prižiūrimas. Naudojant try/catch blokus, klaidų tvarkymo kodas tampa atskiras nuo įprasto srauto.
- Funkcijos/metodai gali susidoroti tik su pasirinktomis išimtimis : Funkcija gali padaryti daug išimčių, bet gali nuspręsti tvarkyti kai kurias iš jų. Kitos išimtys, kurios metamos, bet nepagaunamos, gali būti tvarkomos skambinančiojo. Jei skambinantysis nusprendžia jų negauti, išimtis tvarko skambinančiojo skambinantis asmuo.
C++ kalboje funkcija gali nurodyti išimtis, kurias ji meta naudodama raktinį žodį mesti. Šios funkcijos skambinantis asmuo turi kokiu nors būdu apdoroti išimtį (nurodant ją dar kartą arba gaudamas).
- Klaidų tipų grupavimas : C++ kalboje kaip išimtys gali būti pateikiami ir pagrindiniai tipai, ir objektai. Galime sukurti išimčių objektų hierarchiją, sugrupuoti išimtis vardų erdvėse ar klasėse ir suskirstyti jas į kategorijas pagal tipus.
Išimčių tvarkymo pavyzdžiai C++
Šie pavyzdžiai parodo, kaip naudoti try-catch bloką, kad būtų galima apdoroti išimtis C++.
1 pavyzdys
Toliau pateiktame pavyzdyje parodytos C++ metimo išimtys.
C++
// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >int> numerator = 10;> >int> denominator = 0;> >int> res;> >// check if denominator is 0 then throw runtime> >// error.> >if> (denominator == 0) {> >throw> runtime_error(> >'Division by zero not allowed!'>);> >}> >// calculate result if no exception occurs> >res = numerator / denominator;> >//[printing result after division> >cout <<>'Result after division: '> << res << endl;> >}> >// catch block to catch the thrown exception> >catch> (>const> exception& e) {> >// print the exception> >cout <<>'Exception '> << e.what() << endl;> >}> >return> 0;> }> |
>
>Išvestis
Exception Division by zero not allowed!>
2 pavyzdys
Toliau pateikiamas paprastas pavyzdys, rodantis išimčių tvarkymą C++. Programos išvestis paaiškina try/catch blokų vykdymo eigą.
CPP
// C++ program to demonstate the use of try,catch and throw> // in exception handling.> #include> using> namespace> std;> int> main()> {> >int> x = -1;> >// Some code> >cout <<>'Before try
'>;> >// try block> >try> {> >cout <<>'Inside try
'>;> >if> (x <0) {> >// throwing an exception> >throw> x;> >cout <<>'After throw (Never executed)
'>;> >}> >}> >// catch block> >catch> (>int> x) {> >cout <<>'Exception Caught
'>;> >}> >cout <<>'After catch (Will be executed)
'>;> >return> 0;> }> |
>
>Išvestis
Before try Inside try Exception Caught After catch (Will be executed)>
Išimčių tvarkymo ypatybės C++
1 nuosavybė
Yra specialus gaudymo blokas, vadinamas „catch-all“ bloku, parašytas kaip sugavimas (…), kurį galima naudoti norint sugauti visų tipų išimtis.
Pavyzdys
Tolesnėje programoje int įmetamas kaip išimtis, tačiau int blokas nėra gautas, todėl bus vykdomas blokas catch(...).
CPP
// C++ program to demonstate the use of catch all> // in exception handling.> #include> using> namespace> std;> int> main()> {> >// try block> >try> {> >// throw> >throw> 10;> >}> >// catch block> >catch> (>char>* excp) {> >cout <<>'Caught '> << excp;> >}> >// catch all> >catch> (...) {> >cout <<>'Default Exception
'>;> >}> >return> 0;> }> |
>
listmazgas
>Išvestis
Default Exception>
2 nuosavybė
Netiesioginis tipo konvertavimas nevyksta primityviems tipams.
Pavyzdys
Šioje programoje „a“ netiesiogiai konvertuojamas į int.
CPP
//// C++ program to demonstate property 2: Implicit type> /// conversion doesn't happen for primitive types.> // in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '> << x;> >}> >catch> (...) {> >cout <<>'Default Exception
'>;> >}> >return> 0;> }> |
>
>Išvestis
Default Exception>
Išvestis:
Default Exception>
3 nuosavybė
Jei išmeta išimtis ir niekur nepagauta, programa nutrūksta nenormaliai.
Pavyzdys
Tolesnėje programoje metamas char, bet nėra gaudymo bloko, kuriuo būtų galima sugauti char.
CPP
// C++ program to demonstate property 3: If an exception is> // thrown and not caught anywhere, the program terminates> // abnormally in exception handling.> #include> using> namespace> std;> int> main()> {> >try> {> >throw> 'a'>;> >}> >catch> (>int> x) {> >cout <<>'Caught '>;> >}> >return> 0;> }> |
>
>
Išvestis
terminate called after throwing an instance of 'char'>
Šį neįprastą nutraukimo elgesį galime pakeisti parašydami netikėtą funkciją.
Pastaba : išvestinė klasės išimtis turėtų būti užfiksuota prieš bazinės klasės išimtį.
Kaip ir Java, C++ biblioteka turi a standartinė išimtis klasė, kuri yra pagrindinė klasė visoms standartinėms išimtims. Visi objektai, kuriuos meta standartinės bibliotekos komponentai, yra kilę iš šios klasės. Todėl gaudant šį tipą galima sugauti visas standartines išimtis.
duomenų gavyba
4 nuosavybė
Skirtingai nei Java, C++, visos išimtys yra nepažymėtos, t.y., kompiliatorius netikrina, ar išimtis pagauta, ar ne (žr. tai Norėdami gauti daugiau informacijos). Taigi, funkcijų deklaracijoje nebūtina nurodyti visų nepagautų išimčių. Tačiau tvarkyti išimtis – rekomenduojama tai daryti.
Pavyzdys
Ši programa puikiai kompiliuoja, tačiau idealiu atveju fun() parašas turėtų nurodyti nepažymėtas išimtis.
programinės įrangos kūrimo gyvavimo ciklas
CPP
// C++ program to demonstate property 4 in exception> // handling.> #include> using> namespace> std;> // This function signature is fine by the compiler, but not> // recommended. Ideally, the function should specify all> // uncaught exceptions and function signature should be> // 'void fun(int *ptr, int x) throw (int *, int)'> void> fun(>int>* ptr,>int> x)> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }> |
>
>Išvestis
Caught exception from fun()>
Geresnis būdas parašyti aukščiau pateiktą kodą:
CPP
// C++ program to demonstate property 4 in better way> #include> using> namespace> std;> // Here we specify the exceptions that this function> // throws.> void> fun(>int>* ptr,>int> x)>throw>(> >int>*,>int>)>// Dynamic Exception specification> {> >if> (ptr == NULL)> >throw> ptr;> >if> (x == 0)> >throw> x;> >/* Some functionality */> }> int> main()> {> >try> {> >fun(NULL, 0);> >}> >catch> (...) {> >cout <<>'Caught exception from fun()'>;> >}> >return> 0;> }> |
>
>Išvestis
Caught exception from fun()>
Pastaba : Dinaminės išimties specifikacijos naudojimas buvo nebenaudojamas nuo C++11. Viena iš priežasčių gali būti ta, kad ji gali atsitiktinai nutraukti jūsų programą. Taip gali nutikti, kai pateikiate kito tipo išimtį, kuri nepaminėta dinaminės išimties specifikacijoje. Jūsų programa pati nutrauks veiklą, nes tokiu atveju ji (netiesiogiai) iškviečia terminate (), kuri pagal numatytuosius nustatymus iškviečia abortą ().
5 nuosavybė
C++ programoje try/catch blokai gali būti įdėti. Be to, išimtis gali būti permesta naudojant metimą; .
Pavyzdys
Šioje programoje rodomi try/catch blokų lizdai.
CPP
// C++ program to demonstrate try/catch blocks can be nested> // in C++> #include> using> namespace> std;> int> main()> {> >// nesting of try/catch> >try> {> >try> {> >throw> 20;> >}> >catch> (>int> n) {> >cout <<>'Handle Partially '>;> >throw>;>// Re-throwing an exception> >}> >}> >catch> (>int> n) {> >cout <<>'Handle remaining '>;> >}> >return> 0;> }> |
>
>Išvestis
Handle Partially Handle remaining>
Funkcija taip pat gali pakartotinai mesti funkciją naudodama tą patį metimą; sintaksė. Funkcija gali apdoroti dalį ir paprašyti skambinančiojo tvarkyti likusią dalį.
6 nuosavybė
Kai išmetama išimtis, visi objektai, sukurti uždarančiame bandymo bloke, sunaikinami prieš perduodant valdymą gaudymo blokui.
Pavyzdys
Ši programa demonstruoja aukščiau nurodytą savybę.
CPP
// C++ program to demonstrate> #include> using> namespace> std;> // Define a class named Test> class> Test {> public>:> >// Constructor of Test> >Test() { cout <<>'Constructor of Test '> << endl; }> >// Destructor of Test> >~Test() { cout <<>'Destructor of Test '> << endl; }> };> int> main()> {> >try> {> >// Create an object of class Test> >Test t1;> >// Throw an integer exception with value 10> >throw> 10;> >}> >catch> (>int> i) {> >// Catch and handle the integer exception> >cout <<>'Caught '> << i << endl;> >}> }> |
>
datos konvertavimas į eilutę
>Išvestis
Constructor of Test Destructor of Test Caught 10>
Išimčių tvarkymo apribojimai C++
Išimčių tvarkymas C++ taip pat turi keletą apribojimų:
- Išimtys gali pažeisti kodo struktūrą arba srautą, nes kode sukuriami keli nematomi išėjimo taškai, todėl kodą sunku nuskaityti ir derinti.
- Jei išimčių tvarkymas nebus atliktas tinkamai, taip pat gali nutekėti ištekliai.
- Sunku išmokti parašyti saugų išimties kodą.
- Nėra C++ standarto, kaip naudoti išimčių tvarkymą, todėl egzistuoja daug išimčių tvarkymo praktikos variantų.
Išvada
Išimčių tvarkymas C++ naudojamas netikėtiems įvykiams tvarkyti naudojant try and catch blokus, kad būtų galima efektyviai valdyti problemą. Šis išimčių tvarkymas daro mūsų programas patikimesnes, nes klaidos vykdymo metu gali būti tvarkomos atskirai, taip pat padeda išvengti programos strigimo ir staigaus programos nutraukimo, kai įvyksta klaida.
Susiję straipsniai:
- Populiariausi C++ išimčių tvarkymo interviu klausimai ir atsakymai
- Viktorina apie išimčių tvarkymą C++