Resources‎ > ‎Programming‎ > ‎C++‎ > ‎C++ Tutorial‎ > ‎

Lesson 7


Exception

In C, when you know that your code may produce an error, you would typically need to detect the error where it generated if your program wish to recover from it. Of course, a function, which encounters an error/exception, can just notify the function caller what sort of error it was through its return value.

There are two types of errors in a program:

  • logic_error: usually detectable at the compile time,
  • runtime_error: occur while the program is running.

However, in OOP in general, the program structure is very complex and a function call could have a complex hierarchies. Hence, many OOP langs provide mechanism to allow a program to detect error/exception at different locations form where the actual error/exception occured.

In C++, there are several standard exception/errors are provided:

  • exception : the base class for all standard exception classes
    • logic_error: the base class for program logic error
      • domain_error
      • invalid_argument
      • length_error
      • out_of_range: represents the access of out of range area.
    • runtime_error: the base class for errors, which occur at run-time
      • range_error: represents out of range error during internal calculation.
      • overflow_error: represents overflow during arithmetic calculation
      • underflow_error: represents underflow during arithmetic calculation

When you use C++ class libraries, some of those classes may throw an error/exception. Even some "operator" might throw an error/exception. For instance:

Exception class

operator

description

bad_alloc

new

failure of memory allocation

bad_cast

dynamic_cast

failure of dynamic casting

bad_exception

std::bad_exception

an understudy of unexpected error

bad_typeid

typeid

failure of typeid operator

Practice 1 (Exception)

First, write a function, that compute a simple division of two long values. This function should have its own logic to detect the "divided by zero" and throw an exception.

Practice 2 (Exception)

Try using the above function in the following incomplete code.

#include <iostream>
using namespace std;

/* your div function goes here */

int main() {
    long myarray1[] = (33400, 559990, 325, 5435, 225, 54235};
    long myarray2[] = (242, 13, 0, 35, 0, 55};

    for (...) {
         cout << "(" << myarray1[i] << " / " << myarray2[i] << ") = ";
         //cout << /* call your function here */ << endl;
    }
    return 0;
}

Practice 3 (order of Exception)

Now, we promote the divide function to a class. The following is incomplete code for a class, which stores two arrays and computes division of corresponding elements of the arrays. You task is to complete the code with the following specification:

  • SafeArray class needs to throw range_error exception with a message "index out of range!" when the index for accessing array element is not valid.

  • SafeArray class needs to throw overflow_error exception with a message "divided by zero is not allowed!" when a divisor is zero.

You should be aware of the order of catch block when you detecting multiple errors/exceptions.

#include <iostream>
using namespace std;

namespace {
    const int size = 4;
}

class SafeArray {
    // arrays for dividend and divisor
    long array1[size], array2[size];
public:
    // sets value to array
    void setdata(int index, long lnum, long ldiv) {
         array1[index] = lnum;
         array2[index] = ldiv;
    }
    // returns the result of the specified index
    long operator[](int index) {
        return array1[index] / array2[index];
    }
};

int main() {
    long array1[] = { 3950, 60000, 42000, 80000, 3240 };
    long array2[] = { 20, 870, 0, 500, 0 };
    int max = sizeof array1 / sizeof(long);

    SafeArray sarray;
    for (int i = 0; i < max + 1; i++) {
        // sets the value first.
        sarray.setdata(i, array1[i], array2[i]); 
        cout << "Division result: " << sarray[i] << endl;
    }

    return 0;
}

Practice 4 (new operator and exception)

According to C++ language specification, the new operator could

  • return NULL when new_handler is null pointer value, otherwise

  • throw bad_alloc exception.

Consider the following code that allocate char array to store a set of characters:

char *buffer;
int size;
...
buffer = new char[size]; // assume size is appropriately set.
...

Since there are two different possibilities in how memory allocation failure can be detected. Overload newoperator to

  1. detect memory allocation failure in the above code. (Your code should be able to detect the failure in bothNULL and bad_alloc cases.

  2. only throw bad_alloc when memory allocation failure is detected.



Sample Solutions
Subpages (1): Sample Solutions
Comments