|
Dedication: An early version of the material below was posted a couple of years back on devshed forums. I was the original author of that material. This post is therefore dedicated to Thaminda, the site admin who saw fit to repost the material under his (or her) own name without any attribution or acknowledgement and (worse) making it completely pointless for the author to correct any errors in the original post. — Grumpy —
|
C++ Exceptions
Before getting into advanced concepts related to using exceptions, I'll describe the basics. Most of the following may be gleaned from basic texts, although I've worded things slightly differently.
Exceptions, as an error reporting and recovering mechanism, are a feature of C++ (not C). As described in many texts, the basic usage comes down to
try
{
if (some_condition)
{
ExceptionType x;
throw x;
}
}
catch (ExceptionType x)
{
// recover from error
}
Core features of exceptions include:
#include <string>class X { public: int Type() const {return 1;}; }; class Y : public X { public: int Type() const {return 2;}; };
class Other {}; void FunctionThatThrows() throw (X) { Y y; throw y; // OK; Y is derived from X }
void AnotherFunctionThatThrows() throw (X) { Other a; throw a; // will result in call to abort(); }
void IntermediateFunction(bool call) { std::string hello("Hello");
// Just to illustrate how to do it, we catch all exceptions and rethrow them. // Such a construct gives the same effect that the compiler would give us // anyway try { if (call) FunctionThatThrows(); // the string hello will be cleaned up (i.e. destructed) under all circumstances. // if an exception is not thrown (eg call is false) it will be cleaned up. // if an exception is thrown (eg call is true) it will still be cleaned up. } catch (...) { throw; // rethrow exception } }
int main() { try { std::string x("x"); IntermediateFunction(false); std::string y("y"); // both x and y will be cleaned up } // no exception thrown, so neither of the catch clauses will be invoked catch (X &x) { std::cout << x.Type() << std::endl; } catch (...) { }
try { std::string x("x"); IntermediateFunction(true); // this will throw std::string y("y"); // so this line is never executed // but x will still be cleaned up (i.e. it's destructor will be invoked). } // an exception of type Y (derived from X) will be thrown, so the first // catch clause will have effect catch (X &x) { std::cout << x.Type() << std::endl; // exception of type Y thrown, so value of 2
printed } catch (...) // catch clauses checked in order they are declared. // First clause matches, so this one has no effect { }
return 0; }
