C++ Exception Handling
An exception is a problem that occurs during the execution of a program. A C++ exception is a special condition that arises during the runtime of a program, such as an attempt to divide by zero.
Exceptions provide a way to transfer control of a program. C++ exception handling involves three keywords: try, catch, and throw.
throw: When a problem occurs, the program throws an exception. This is done using the throw keyword.
catch: A place to handle the problem by catching the exception with an exception handler. The catch keyword is used to catch exceptions.
try: A block of code that identifies a specific exception to be activated. It is usually followed by one or more catch blocks.
If a block throws an exception, the method to catch the exception uses the try and catch keywords. Code that may throw an exception is placed inside a try block, which is known as guarded code. The syntax for using a try/catch statement is as follows:
try
{
// guarded code
}catch( ExceptionName e1 )
{
// catch block
}catch( ExceptionName e2 )
{
// catch block
}catch( ExceptionName eN )
{
// catch block
}
If the try block can throw different exceptions under different circumstances, you can list multiple catch statements to catch different types of exceptions.
Throwing an Exception
You can throw an exception in a code block using the throw statement. The operand of the throw statement can be any expression, and the type of the result of the expression determines the type of the exception thrown.
Here is an example of throwing an exception when attempting to divide by zero:
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
Catching an Exception
The catch block follows the try block and is used to catch exceptions. You can specify the type of exception you want to catch, which is determined by the exception declaration in parentheses after the catch keyword.
try
{
// guarded code
}catch( ExceptionName e )
{
// code to handle ExceptionName exception
}
The above code will catch an exception of type ExceptionName. If you want the catch block to handle any type of exception thrown by the try block, you must use an ellipsis ... in the parentheses of the exception declaration, as shown below:
try
{
// guarded code
}catch(...)
{
// code to handle any exception
}
Below is an example that throws a division by zero exception and catches it in the catch block.
Example
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
Since we throw an exception of type const char, we must use const char in the catch block to catch it. When the above code is compiled and executed, it produces the following result:
Division by zero condition!
C++ Standard Exceptions
C++ provides a set of standard exceptions defined in <exception> that we can use in our programs. They are organized in a parent-child class hierarchy, as shown below:
Defining New Exceptions
You can define new exceptions by inheriting and overriding the exception class. The following example demonstrates how to implement your own exception using the std::exception class:
Example
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception
{
const char * what () const throw ()
{
return "C++ Exception";
}
};
int main()
{
try
{
throw MyException();
}
catch(MyException& e)
{
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
}
catch(std::exception& e)
{
// Other errors
}
}
This will produce the following result:
MyException caught
C++ Exception
Here, what() is a public method provided by the exception class, which has been overridden by all subclasses of exception. This returns the cause of the exception.