Home C++ Introduction Decisions Loops Input/Output Functions Stack and Heap References Arrays Searching and Sorting Recursion Pointers Character and Strings Structures Classes Inheritance Exceptions Templatess STL Modern C++ Misc Books ----


Exceptions


Contents

Object Oriented Style

Basics

An exception is thrown by a function. If that function
does not handle the exception then it is thrown again
to the function that called it and so on. The exception
object is kept in a special memory but the C++ standard
does not madate where and the implementation is left to the
compiler.

It is often in a speical heap but the not regular heap
that we create objects in using "new" . It's only used
by the exception handling mechanism. It is not going to
be stored on the stack because if there are many functions
in a chain and we are destroying each stack frame then we
have to keep copying the exception obect.





File: except1.cpp
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int ErrorCode = 0 ;
int divideOperation1( int x1, int y1 )
 {
     ErrorCode = 0 ;
     if ( y1 == 0 )
       {
           ErrorCode = -1 ;
           return 0 ;
        }
    return ( x1 / y1 ) ;
 }

int divideOperation2( int x1, int y1 )
{
    ErrorCode = 0 ;
    if ( y1 == 0 )
      {
         throw  "Divide by zero." ;
      }
     return ( x1 / y1 ) ;
}

int main()
{
    divideOperation1 ( 4 ,  0 ) ;
    if ( ErrorCode == -1 )
      cout << "Error divisor is zero." << endl ;

        try
         {
              divideOperation2 ( 4 ,  0 ) ;
         }
        //catch ( const string& str1 )
        catch ( const char* str1 )
        {
            cout << str1  << endl ;
        }
    return 0;
}
Output:

$ ./a.exe

Error divisor is zero.

Divide by zero.

This program shows the old way of handling errors using the function:
"divideOperation1" and the new way in the function ""divideOperation2" .

    if ( y1 == 0 )
      {
         throw  "Divide by zero." ;
      }

 This code is inside the function "function2" . What happens when
 "throw" is encountered ? In this case there is no catch otherwise control
 will move to the catch part. The system will clean up any local objects
 and the function will not execute any more code and the exception being
 thrown "const char*" is thrown to the calling code.

	    try
	     {
			  divideOperation2 ( 4 ,  0 ) ;
		 }
		catch ( const char* str1 )
		{
			cout << str1  << endl ;
		}

The "divideOperation2" in the calling code is enclosed in a "try" block so if it throws
an exception the control comes to the catch block. If the object being thrown matches
the catch argument then the catch code is executed. The code following the "throw" is not
executed. So if there were any statements followig the code "throw  Divide by zero." ; they
would not be executed. The local objects get destroyed as the function comes out with the
throw statement.


If the argument is not caught then it will be passed to the calling function. If the calling function is the "main" function and the exception is not caught then the program terminates.

File: except2.cpp
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int ErrorCode = 0 ;
int divideOperation1( int x1, int y1 )
 {
     ErrorCode = 0 ;
     if ( y1 == 0 )
       {
           ErrorCode = -1 ;
           return 0 ;
        }
    return ( x1 / y1 ) ;
 }

int divideOperation2( int x1, int y1 )
{
    ErrorCode = 0 ;
    if ( y1 == 0 )
      {
         throw  "Divide by zero." ;
      }
     return ( x1 / y1 ) ;
}

int main()
{
    divideOperation1 ( 4 ,  0 ) ;
    if ( ErrorCode == -1 )
      cout << "Error divisor is zero." << endl ;

      divideOperation2 ( 4 ,  0 ) ;
      cout << "End of Main."  << endl ;

    return 0;
}

$ g++ except2.cpp ; ./a.exe
Error divisor is zero.
terminate called after throwing an instance of 'char const*'
Aborted (core dumped)

In the above code we have modified "except2.cpp" to have the
statements:

      divideOperation2 ( 4 ,  0 ) ;
      cout << "End of Main."  << endl ;

Since the exception is not caught and we are in the "main" function the
system will not execute any more statements
( "End of Main" is not executed )
and the program will abort as
shown in the output.
There is a slight disadvantage to the exception handling and that is the control moves to the catch block and it may be difficult to retry the function calls as we are out of the normal coding block.

Excercise

1) What does the below program print ?
File: basic_ex1.cpp
#include <iostream>
#include <fstream>

using namespace std;

class A
{
  public:
  A()
   {
     cout << "A: constructor: "  << endl ;
   }

   ~A()
    {
      cout << "A: destructor: "  << endl ;
    }
};

void function2()
{
   A objectA1  ;
   try
    {
      cout << "Inside function2: Step 1" << endl ;
      throw 10 ;
      cout << "Inside function2: Step 2" << endl ;
    }
   catch( int& x1 )
    {
        cout << "Inside function2: Catch Step 1" << endl ;
        throw x1 ;
        cout << "Inside function2: Catch Step 2" << endl ;
    }
   cout << "End of function2." << endl ;
}


void function1()
{
   A objectA1  ;
   cout << "Inside function1: Step 1" << endl ;
   function2() ;
   cout << "End of function1." << endl ; //A
}

int main()
{
     try
      {
          function1() ;
          cout << "After function 1 in main." << endl ; //B
      }
     catch ( int& x1  )
      {
        cout << "Inside catch. main"   << endl ;
      }

  cout << "End of main:" << endl ;

 return 0;

}