Excepție de manipulare în c

Limba C prezintă posibilități foarte limitate pentru programator de a gestiona excepțiile care apar în timpul funcționării programului. În acest sens, C ++ este mult mai dezvoltat decât C. Aici programatorul are oportunități mult mai mari de a gestiona excepțiile directe. Comitetul de dezvoltare a standardelor C ++ a oferit o formă foarte simplă, dar puternică de tratare a excepțiilor.

Zilele întunecate din

O funcție tipică scrisă în C arată cam așa:

Nu arată prea mult, nu-i așa? Depindeți în întregime de valorile pe care funcțiile le revin și pentru fiecare eroare în care aveți nevoie constant de codul care o gestionează. Dacă, să zicem, lucrați într-o funcție cu cel puțin 10 indicatori (alocați memorie, eliberați-o etc.), atunci jumătate din codul funcției va fi ocupat de codul de eroare. Aceeași situație va fi și în codul care numește această funcție, deoarece aici este necesar să procesăm toate codurile de eroare returnate.

Încercați-catch-aruncare

Să aruncăm o privire la elementele de bază ale tratării excepțiilor în C ++. Pentru a lucra confortabil cu excepțiile în C ++, trebuie să cunoașteți doar trei cuvinte cheie:

  • încercați - începutul blocului de excepție;
  • captura (captură) - începutul blocului care captează excepția;
  • aruncarea (aruncarea) este un cuvânt cheie care generează o excitație.

Și acum un exemplu care demonstrează modul de aplicare a ceea ce ați învățat:

Dacă executați acest fragment de cod, obținem următorul rezultat:

Acum comentați aruncarea liniei 1; iar funcția va returna următorul rezultat:

După cum puteți vedea, totul este foarte simplu, dar dacă acest lucru este aplicat în mod înțelept, această abordare vă va părea un instrument foarte puternic de gestionare a erorilor. Captura poate "prinde" orice tip de date, precum și aruncarea poate "arunca" date de orice tip. Ie arunca AnyClass (); va funcționa corect, așa cum va prinde (AnyClass d) <>;.

Așa cum am menționat deja, captura captează date de orice tip, dar nu este necesară specificarea unei variabile. Ie acesta va functiona bine asa:

Puteți, de asemenea, "prinde" toate excepțiile:

Elipsa în acest caz arată că toate excepțiile vor fi prinse. Cu această abordare, nu puteți specifica numele unei variabile. În cazul în care „arunca“ date nonstandard (instanțe ale claselor, vă structuri etc.), este mai bine să „captura“ link-ul lor, în caz contrar toate „arunca“ variabilă va fi copiat în stivă în loc să treacă doar un pointer la l. Dacă sunt aruncate date de mai multe tipuri și doriți să prindeți o anumită variabilă (sau mai degrabă, o variabilă de un anumit tip), puteți utiliza mai multe blocuri de captură capturați propriul tip de date:

Crearea "excepțiilor"

Când se ridică o excepție, programul scanează stiva de funcții până când găsește captura corespunzătoare. Dacă declarația de captură nu este găsită, STL va face față excepției într-un handler standard care face totul mai puțin grațios decât ceea ce ați putea face, arătând un mesaj de neînțeles (pentru utilizatorul final) și, de obicei, crashing programul.

Cu toate acestea, punctul mai important este că în timp ce stiva de funcții este privită în sus, sunt chemați distrugătorii tuturor claselor locale, deci nu trebuie să vă faceți griji pentru eliberarea memoriei etc.

Supraîncărcarea operatorilor globali noi / ștergeți

Și acum aș vrea să vă trimit la articolul "Cum să detectați o scurgere de memorie". Descrie cum se detectează o gestionare necorespunzătoare a alocării memoriei în programul tău. Puteți întreba ce înseamnă supraîncărcarea operatorului? Dacă supraîncărcați standardul nou și ștergeți, există posibilități largi pentru erorile de urmărire (iar erorile sunt deseori critice) cu excepții. De exemplu:

Aceasta, la prima vedere, pare a fi mai lungă decât testul standard din C "și este NULL?". Dar dacă programul alocă o duzină de variabile dinamice, atunci această metodă se justifică.

Operatorii aruncă fără parametri

Deci, am văzut cum noua metodă de tratare a erorilor este convenabilă și simplă. Blocul de încercare-captură poate conține blocuri try-capture imbricate și dacă declarația de captură corespunzătoare nu este definită la nivelul atasamentului curent, excepția va fi prinsă la un nivel mai înalt. Singurul lucru pe care trebuie să-l amintiți este că operatorii care urmează aruncarea nu vor fi executați niciodată.

Această metodă poate fi utilizată în cazurile în care nu este necesar să transmiteți date către blocul de captură.

cerere

Iată un exemplu despre modul în care toate cele de mai sus pot fi utilizate într-o aplicație specifică. Să presupunem că aveți o clasă cMain și o instanță a acestei clase în program: class cMain ; cMain Main;

Și în funcția principal () sau WinMain (), puteți folosi această clasă într-un fel astfel:

Ciclul principal al programului poate arăta astfel:

concluzie

Metoda de tratare a excepțiilor prezentată în articol este un instrument convenabil și puternic, dar numai tu decideți dacă îl utilizați sau nu. Se poate descărca exact - metoda de mai sus vă va ușura viața. Dacă doriți să aflați mai multe despre excepții, consultați publicația Deep C ++ de pe serverul MSDN.

Articole similare