Monday, 17 November 2014

Exception Handling in C++ with examples

Exception Handling in C++ with examples:

In C++ we have the great feature that is EXCEPTION HANDLING. The key words that are used to handle the exceptions is
 try, catch, throw

Description about each keyword is explained below
try – it holds the code that can throw an exception.

catch: This represents a block of code that is executed when a particular exception is thrown.

throw: This is used to throw an exception.



Why we need Exception Handling? 

There are three situations that we need to go for the exception handling over error handling.

a. Exceptions are used to handle the errors generated by our programs by transferring control to functions called handlers.
b. To catch exceptions we have to place our code on which we want exception handling in the try block. If an exception occurs the control is passed to the handler, otherwise the handlers are ignored.
c. The try block contains the code that can produce the exceptions and the catch block holds the error handlers are declared in the try block.


1) Separation of Error Handling code from Normal Code: 
In traditional error handling codes, there are always if else conditions to handle errors. These conditions and the code to handle errors get mixed up with the normal flow. This makes the code less readable and maintainable. With try catch blocks, the code for error handling becomes separate from the normal flow.

2) Methods can handle any exceptions, what they require: 
A function can throw many not caught can be handled by caller. If the caller chooses not to catch them, then the exceptions are handled by caller of the caller. In C++, a function can specify the exceptions that it throws using the throw keyword. The caller of this function must handle the exception in some way (either by specifying it again or by catching it)

3) It is possible to grouping of Error Types: 
In C++, both basic types and objects can be thrown as exception. We can create a hierarchy of exception objects, group exceptions in namespaces or classes, categorize them according to types.

Exception Handling in C++:

Point 1) Let us try our first exception handling program

#include <iostream>
using namespace std;
 int main()
{
   int x = -1;
    // Some code
   cout << "I am Before try block \n" << endl;
   try {
      cout << "I am in the try block \n" << endl;
      if (x < 0)
      {
         throw x;
         cout << "After throw, it never executes \n" << endl;
      }
   }
   catch (int x ) {
      cout << "Exception Caught by the catch block\n" << endl;
   }
    cout << "After catch it will be executed \n" << endl;
   return 0;
}

The output of the above program is that will explain the sequence of the try, catch blocks.
I am Before try block
I am in the try block
Exception Caught by the catch block
After catch it will be executed

Type 2) In C++ we have special catch block is available which is called as ‘catch all’ catch(…) that can be used to catch all types of exceptions
See the below example:
#include <iostream>
using namespace std;
 int _tmain (int argc, _TCHAR* argv[])
{
    try  {
       cout << "I am in the try block"<< endl;
       throw 5;
    }
    catch (char *pchExc)  {
      cout << "Caught the exception that is raised by normal integer " << pchExc << endl;
    }
    catch (...)  {
        cout << "I am in the Default Exception\n" << endl;
    }
    return 0;
}


In the above example an int is thrown as an exception, but there is no catch block for int, so catch(…) block will be executed.
The output of the above program:
I am in the try block
I am in the Default Exceptionbr />
Point 2) Implicit type conversion doesn’t happen for primitive types.
Below is the example, in the following program ‘a’ is not implicitly converted to int
#include <iostream>
using namespace std;
 int _tmain (int argc, _TCHAR* argv[])
{
    try  {
       cout << "I am in the try block" << endl;
       throw 'a';
    }
    catch (int x)  {
        cout << "I am in the caught block" << "\n" << x << endl;
    }
    catch (...)  {
        cout << "Default Exception\n" << endl;
    }
    return 0;
}

The output of the above program is:
I am in the try block
Default Exception

Point 3) If an exception is thrown and not caught anywhere, the program terminates abnormally.
The below example a character is thrown, but there is no catch block to catch a character.
#include <iostream>
using namespace std;
 int _tmain (int argc, _TCHAR* argv[])
{
       try  {
      cout << "I am in the try block" << endl;
      throw 'a';
    }
    catch (int x)  {
         cout << "I am in the caught block";
    }
    return 0;
}
The output of the above program is:
I am in the try block

Application gets terminated, after throwing an instance of 'char'


Point 4)To handle the exceptions we need to remember some basic points:

The Derived class exception should be caught before a base class exception.
There are some standard exceptions available in C++.
All objects thrown by components of the standard library are derived from this class. Therefore, all standard exceptions can be caught by catching this type

Point 5) C++ compilers are unable to check  that the exceptions that are catch are not:

 Below is an example that helps us to understand the list unchecked exceptions.
#include <iostream>
using namespace std;
void MyTestFun(int *iPVal, int ixVal);
int _tmain (int argc, _TCHAR* argv[])
{
     try {
       cout << "I am in the try block that contains the MyTestFun()"<< endl;
       MyTestFun(NULL, 0);
    }
    catch(...) {
        cout << "Caught exception from MyTestFun()"<< endl;
    }
    return 0;
}
 This function signature is fine by the compiler, but not recommended.
 Ideally, the function should specify all uncaught exceptions and function
void MyTestFun(int *iPVal, int ixVal) throw (int *, int)

void MyTestFun(int *iPVal, int ixVal)
{
    if (iPVal == NULL)
        throw iPVal;
    if (ixVal == 0)
        throw ixVal;   
}

The Output of the above program is:
I am in the try block that contains the MyTestFun()
Caught exception from MyTestFun()
Point 6) In C++, try-catch blocks can be nested. Also, an exception can be re-thrown using “throw; ”
Let us see the below program:
#include <iostream>
using namespace std;
int _tmain (int argc, _TCHAR* argv[])
{
     try {
             cout << "I am in first try block " << endl;
        try  {
                cout << "I am in second try block " << endl;
            throw 20;
        }
        catch (int n) {
          cout << "I am in the first catch block, Here I am Re-throwing an exception" << endl;
          throw; 
        }
    }
    catch (int n) {
        cout << "I am in the second catch block" << endl;
    }
    return 0;
}
The result of the above program is:
I am in first try block
I am in second try block
I am in the first catch block, Here I am Re-throwing an exception
I am in the second catch block
From the above program we can understand that a function can also re-throw a function using same “throw; “. A function can handle a part and can ask the caller to handle remaining.

Point 7) When an exception is thrown, all objects created inside the enclosing try block are destructed before the control is transferred to catch block.
#include <iostream>
using namespace std;
class myClass {
public:
   myClass () {
     cout << "I am Constructor of myClass " << endl;
   }
  ~myClass () {
    cout << "I am Destructor of myClass "  << endl;
  }
};
int _tmain (int argc, _TCHAR* argv[])
{ 
  try {
    myClass ocTest;
    throw 10;
  } catch(int i) {
    cout << "I am in the caught" << i << endl;
  }
}
The output of the above program is
I am Constructor of myClass
I am Destructor of myClass
I am in the caught 10


No comments: