Definition
Exceptions occur because of problems arising at runtime (memory overflow, data outside the prescribed limits) and provide a way to react to exceptional circumstances.
Try, Catch, Throw
try {
// code that could throw an exception
}
[ catch (exception-declaration) {
// code that executes when exception-declaration is thrown
// in the try block
}
[catch (exception-declaration) {
// code that handles another exception type
} ] . . . ]
// The following syntax shows a throw expression:
throw [expression]
The try, throw, and catch statements implement exception handling.
The code after the try clause is the guarded section of code. The throw expression raises an exception. The code block after the catch clause is the exception handler, and handles the exception thrown by the throw expression. The exception-declaration statement indicates the type of exception the clause handles. The type can be any valid data type, including a C++ class.
The operand of throw is syntactically similar to the operand of a return statement.
Standard Exceptions
The C++ Standard library provides a base class named exception specifically designed to declare objects to be thrown as exceptions, which is defined in the <exception> header file under the namespace std.
| Exception | Description |
bad_alloc | thrown by new on allocation failure |
bad_cast | thrown by dynamic_cast when fails with a referenced type |
bad_exception | thrown when an exception type doesn't match any catch |
bad_typeid | thrown by typeid |
ios_base::failure | thrown by functions in the iostream library |
References
Example 1
ProblemThis simple program illustrates 2 nested try-catch.
Workings#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
try
{
try
{
throw 5;
}
catch(int e)
{
throw 10;
}
}
catch(int e)
{
cout <<"Exception "<<e<<"."<<endl;
}
_getch();
return 0;
}
SolutionOutput:
Exception 10.
Example 2
ProblemThe following illustrates the functionality of try-catch block.
Workings#include <iostream>
#include <conio.h>
using namespace std;
void function(int i)
{
switch(i)
{
case 0: throw 0;
break;
case 1: throw 10;
break;
case 5: throw 100;
break;
default: throw -1;
break;
}
}
int main()
{
int i;
cout <<"i=";
cin >>i;
try
{
function(i);
}
catch(int e)
{
cout <<"Exception "<<e<<"."<<endl;
}
_getch();
return 0;
}
SolutionOutput:
i=3 Exception -1.
Example 3
ProblemThis program shows how to use different standard exceptions.
Workings#include <iostream>
#include <new>
#include <cassert>
#include <typeinfo>
#include <fstream>
#include <conio.h>
using namespace std;
void throwEx() throw(char,bad_exception)
{
throw 10;
}
int main()
{
try
{
int option;
do
{
cout <<"What kind of exception do you want to throw ? \n";
cout <<"1 - create a heap exception"<<endl;
cout <<"2 - create a dynamic cast exception"<<endl;
cout <<"3 - create typeid exception"<<endl;
cout <<"4 - create base_failure"<<endl;
cout <<"5 - create bad_exception"<<endl;
cin >>option;
}while(option<1 || option>6);
switch(option)
{
case 1: // create a heap exception
for(int i=0;i<100;i++)
{
new int[100000000];
}
break;
case 2: // create a dynamic cast exception
{
class Base {public:virtual void virtualfunc() const {} };
class Derived: public Base {public: virtual void virtualfunc() const {} };
Base base_instance;
Base& ref_base = base_instance;
Derived& ref_derived = dynamic_cast<Derived&>(ref_base);
}
break;
case 3: // create typeid exception
{
class Base{} * base = 0;
cout <<typeid(*base).name();
}
break;
case 4:
{
ifstream f("no file with this name");
f.exceptions(f.failbit);
}
break;
case 5:
throwEx();
break;
}
}
catch(bad_alloc & ex)
{
cout <<"Memory exception thrown : "<<ex.what()<<endl;
}
catch(bad_cast & ex)
{
cout <<"A bad cast was tried : "<<ex.what()<<endl;
}
catch(bad_typeid & ex)
{
cout <<"A bad typeid was tried : "<<ex.what()<<endl;
}
catch(ios_base::failure & ex)
{
cout <<"A bad ifstream was tried : "<<ex.what()<<endl;
}
catch(bad_exception & ex)
{
cout <<"Nobody catched this except1ion...\n";
}
catch(exception & ex)
{
cout <<"Unknown exception...\n";
}
cout <<"Here...\n";
_getch();
return 0;
}
SolutionOutput:
What kind of exception do you want to throw ?
1 - create a heap exception
2 - create a dynamic cast exception
3 - create typeid exception
4 - create base_failure
5 - create bad_exception
2
A bad cast was tried : Bad dynamic_cast!
Here...
Example 4
ProblemThis program illustrates how to create your own exception class that inherits from std::exception.
Workings#include <iostream>
#include <conio.h>
#include <exception>
#include <string>
using namespace std;
class NullPointerException: public exception
{
private:
string errMsg;
public:
NullPointerException(char* message): exception(message) {};
virtual ~NullPointerException() throw() {};
};
void copymem(void * dest, void * source, int size) throw(NullPointerException)
{
if(dest == NULL || source == NULL)
throw NullPointerException("copymem was called with null parameter(s)");
memcpy(dest,source,size);
}
int main (void)
{
try
{
char source[10] = "test text";
char * destination = NULL;
copymem(destination,source,10);
}
catch(NullPointerException & ex)
{
cout <<ex.what();
}
_getch();
return 0;
}
SolutionOutput:
copymem was called with null parameter(s)
Example 5
ProblemThis program shows how to use .NET Exceptions class.
Workingsusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{ // generate error
int error = 3;
if (error == 1) // divide by zero
{
int xp = 1;
xp--;
float x = 1 / xp;
}
if (error == 2) // file open
{
TextReader txt = new StreamReader("nofile");
txt.Close();
}
if (error == 3)
{
throw new Exception("Test exception");
}
}
catch (ArithmeticException ex)
{
Console.WriteLine(ex.Message.ToString());
}
catch (FileNotFoundException ex)
{
Console.WriteLine(ex.Message.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
finally
{
Console.WriteLine("This block was executed either way...");
}
Console.ReadKey();
}
}
}
SolutionOutput:
Test exception
This block was executed either way...