Exceptions and Error Handling

    Reading: Dietel sections 13.1 - 13.12

Local Error Handling

Exceptions

Example: Rational number arithmetic

class Rational
{
    public:  // Also accessors, mutators, etc.

                Rational (int numerator = 0, int denominator = 1);

                Rational operator + (const Rational& lhs) const;
                Rational operator - (const Rational& lhs) const;
                Rational operator * (const Rational& lhs) const;
                Rational operator / (const Rational& lhs) const;

   private:
                int numerator;
                int denominator;
};

class DivideByZero        // Use only to signal an error condition
{
    public:
                DivideByZero ( Rational lhs );
                Rational GetOperand ( );
    private:
                Rational lhs;
};

Rational Rational :: operator / ( const Rational& rhs )
{
Rational result;

if ( rhs.numerator == 0 ) 
    throw DivideByZero ( *this );

else
    return Rational ( numerator * rhs.denominator, denominator * rhs.numerator);
}

Rational DivideByZero :: GetOperand ( )
{
return lhs;
}

void foo (Rational a, Rational b )
{
    Rational c;
    try
    {
        c = a / b;
    }
    catch ( DivideByZero& dbz )  // Catching by reference is preferred
   
                                               //  Otherwise exception's copy constructor used 
    {
        cout << "Tried to divide " << dbz.GetOperand ( ) << "by zero!" << endl;
        c = 0;
    }

   // whatever else...

}

    foo can't detect the divide-by-zero; operator's implementation is hidden

    operator can't handle the divide-by-zero; may be critical, or may be ignored

 

Behavior of throw / catch blocks

What if the catch block can't handle an exception?

Try / catch blocks can be nested

Partial Error Handling

Specifying a Function's Exception Throws