Cap. 6. Tratarea exceptiilor

Este un fenomen "natural" ca in programe sa se strecoare erori, de diverse naturi. Activitatea de programare implica si actiuni mai putini placute, adica testarea, depanarea si corectarea erorilor. Costurile de indepartare a erorilor creste de obicei direct proportional cu intarzierea din cadrul procesului de dezvoltare cand sunt descoperite.
Trebuie insa inteleasa diferenta dintre erori (bug-uri) si exceptii. Exceptiile sunt situatiile neasteptate aparute in cadrul sistemului care ruleaza un program. Programele trebuie sa fie pregatite pentru a trata aceste situatii exceptionale.
In C++ s-a realizat un mecanism facil de tratare a exceptiilor. Astfel, o exceptie este un obiect a carui adresa este trimisa dinspre zona de cod unde a aparut problema catre o zona de cod care trebuie sa o rezolve.
Pasii care trebuiesc in general urmati in vederea tratarii exceptiilor in cadrul programelor C++ sunt:
1. se identifica acele zone din program in care se efectueaza o operatie despre care se cunoaste ca ar putea genera o exceptie, si se marcheaza in cadrul unui bloc de tip try. In cadrul acestui bloc, se testeaza conditia de aparitie a exceptiei, si in caz pozitiv se semnaleaza aparitia exceptiei prin intermediul cuvantului cheie throw;
2. se realizeaza blocuri de tip catch pentru a capta exceptiile atunci cand acestea sunt intalnite.
Blocurile catch urmeaza un bloc try, in cadrul carora sunt tratate exceptiile.
Sintaxa pentru try:

try
{
// cod
throw TipExceptie;
}


Sintaxa pentru throw:

throw TipExceptie;

Sintaxa pentru catch:

catch(TipExceptie)
{
// cod tratare exceptie
}


Daca TipExceptie este "...", este captata orice exceptie aparuta.

Dupa un bloc try, pot urma unul sau mai multe blocuri catch. Daca exceptia corespunde cu una din declaratiile de tratare a exceptiilor, aceasta este apelata. Daca nu exista definita nici o rutina de tratare a exceptiei, este apelata rutina predefinita, care incheie executia programului in curs. Dupa ce rutina este executata, programul continua cu instructiunea imediat urmatoare blocului try.
TipExceptie nu este altceva decat instantierea unei clase vide (care determina tipul exceptiei), putand fi declarat ca:

class TipExceptie {};

In continuare prezentam un exemplu de program care utilizeaza tratarea exceptiilor.

#include <iostream.h>

#define MAXX	80
#define MAXY	25

class Point
{
 public:

  class xZero {};
  class xOutOfScreenBounds {};

  Point(unsigned __x, unsigned __y)
    {
    x = __x;
    y = __y;
    }

  unsigned GetX()
    {
    return x;
    }

  unsigned GetY()
    {
    return y;
    }

  void SetX(unsigned __x)
    {
    if(__x > 0)
      if(__x < = MAXX)
        x = __x;
       else
        throw xOutOfScreenBounds();
     else
      throw xZero();
    }

  void SetY(unsigned __y)
    {
    if(__y > 0)
      if(__y < = MAXY)
        y = __y;
       else
        throw xOutOfScreenBounds();
     else
      throw xZero();
    }

 protected:
  int x, y;
};

main()
{
  Point p(1, 1);
  try
    {
    p.SetX(5);
    cout << "p.x successfully set to " << p.GetX() << "." << endl;
    p.SetX(100);
    }
  catch(Point::xZero)
    {
    cout << "Zero value!\n";
    }
  catch(Point::xOutOfScreenBounds)
    {
    cout << "Out of screen bounds!\n";
    }
  catch(...)
    {
    cout << Unknown exception!\n";
    }
}

Datorita faptului ca exceptia este instantierea unei clase, prin derivare pot fi realizate adevarate ierarhii de tratare a exceptiilor. Trebuie avuta insa in vedere posibilitatea de aparitie a unor exceptii chiar in cadrul codului de tratare a unei exceptii, situatii care trebuie evitate.

In urmatorul capitol va fi prezentata notiunea de template.


Realizat de Dragos Acostachioaie, ©1998
http://www.biosfarm.ro/~dragos