#include <iostream.h>
#include <string.h>

// clasa Exceptie implementeaza un obiect exceptie, care contine
// informatie despre tipul exceptiei

class ExceptieObiectuala
{
public:
   char* tip_exceptie;
   ExceptieObiectuala(char* arg=NULL);
   ~ExceptieObiectuala();
};

ExceptieObiectuala::ExceptieObiectuala(char* arg)
{
   if(arg!=NULL)
   {
	   tip_exceptie = new char[strlen(arg)+1]; 
	   strcpy(tip_exceptie, arg);
   }
   else
	   tip_exceptie = NULL;
}

ExceptieObiectuala::~ExceptieObiectuala()
{
   if(tip_exceptie!=NULL)
	   delete tip_exceptie;
}

// clasa care emite exceptii..

class Test
{
public:
   // emite o exceptie de tip string
   void ThrowString();

   //emite o exceptie de tip Exception
   void ThrowExceptieObiectuala();
};

void Test::ThrowString()
{
//   throw "EXCEPTIE TIP SIR DE CARACTERE!!";
   throw int(4);
}

void Test::ThrowExceptieObiectuala()
{
   throw *new 
	   ExceptieObiectuala("EXCEPTIE DE CLASA ExceptieObiectuala!!");
}

void main()
{
   Test t;

   // emite exceptie de tip string
   try{
	   t.ThrowString();
   }
 //  catch(char* sir1_Exceptie){
 //     cout<<sir1_Exceptie<<"\n";
   catch (int exceptie_intreaga) {
	   cout << "EXCEPTIE DE VALOARE " << exceptie_intreaga << "\n";
   }
   catch(ExceptieObiectuala& ref_exceptie1){
      cout<<ref_exceptie1.tip_exceptie<<"\n";
   }
   catch(...){ // asa se trateaza exceptiile neinterceptate
         // în alte blocuri
    cout << "ALT FEL DE EXCEPTIE!\n";
  }

   // emite un obiect exceptie de clasa ExceptieObiectuala
   try{
      t.ThrowExceptieObiectuala();
   }
      catch(char* sir2_Exceptie)
   {
	   cout<< sir2_Exceptie <<"\n";
   }
   catch(ExceptieObiectuala& ref_exceptie2)
   {
	   cout<< ref_exceptie2.tip_exceptie <<"\n";
   }
}
