FILE *f;
try
{
f = fopen( "myfile.txt", "r" );
if ( f == NULL )
throw "opening file";
}
catch ( const char* p )
{
printf( "Error %s while %s", strerrror(errno), p );
exit();
}
try
{
// dangerous stuff
}
catch (overflow_error oe)
{
printf( "Overflow error\n" );
}
catch (exception e)
{
printf( "Some exception happened. Deal.\n" );
throw; // same as throw e; in the context of an exception handler
}
catch (...)
{
// this would catch anything, even a throw "foobar";
}
the first exception handler is used if there was an overflow error in
g and the second handler is used if there was any other type
of exception. Exception handlers are examined in order to see if
they match the type whenever an exception is raised, so reversing the
order of the above handlers wouldn't be a good idea.
Well, everything works the same way except that you must declare what kind of exceptions g can throw. For example:
void g() throw(int)
{
throw 5;
}
void f()
{
try
{
g();
printf( "This will never be printed.\n" );
}
catch( int i )
{
// stuff
}
}
is valid, but it would give a run time error if you didn't have
the throw(int) specifier in g's declaration.
void (*pf1)(); // no exception specification
void (*pf2) throw(A);
void f()
{
pf1 = pf2; // ok: pf1 is less restrictive
pf2 = pf1; // error: pf2 is more restrictive
}
or
class B {
virtual void f() throw (int, double);
virtual void g();
};
class D: B {
void f(); // ill-formed
void g() throw (int); // OK
};