C++ Exception Handling
In this tutorial, we will learn about Excaption Handling in C++ with the help of examples.
Exception Handling
One of the advantages of C++ over C is Exception Handling. Exception Handling in C++ is a process to handle runtime errors. We perform exception handling so the normal flow of the application can be maintained even after runtime errors.
In C++, exception is an event or object which is thrown at runtime. All exceptions are derived from std::exception class. It is a runtime error which can be handled. If we don't handle the exception, it prints exception message and terminates the program
There are two types of exceptions:
a) Synchronous
b) Asynchronous (Ex:which are beyond the program’s control, Disc failure etc).
Exception Handling Keywords
C++ provides following specialized keywords for this purpose:
1. throw- Used to throw an exception. Also used to list the exceptions that a function throws, but doesn’t handle itself.
2. catch- represents a block of code that is executed when a particular exception is thrown.
3. try- represents a block of code that can throw an exception.
Why Exception Handling?
Following are main advantages of exception handling over traditional error handling.
1. You will separate your error handling code from your normal code. The code will be more readable and easier to maintain.
2. Functions can handle the exceptions they choose. Even if a function throws many exceptions, it will only handle some. The caller will handle the uncaught exceptions.
3. 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.
Syntax
The try/catch takes this syntax:
try { // the protected code } catch( Exception_Name exception1 ) { // catch block } catch( Exception_Name exception2 ) { // catch block } catch( Exception_Name exceptionN ) { // catch block }
- Although we have one try statement, we can have many catch statements.
- The ExceptionName is the name of the exception to be caught.
- The exception1, exception2, and exceptionN are your defined names for referring to the exceptions.
C++ Standard Exceptions
There are some standard exceptions in C++ under
- std::exception - Parent class of all the standard C++ exceptions.
- logic_error - Exception happens in the internal logical of a program.
- domain_error - Exception due to use of invalid domain.
- invalid argument - Exception due to invalid argument.
- out_of_range - Exception due to out of range i.e. size requirement exceeds allocation.
- length_error - Exception due to length error.
- runtime_error - Exception happens during runtime.
- range_error - Exception due to range errors in internal computations.
- overflow_error - Exception due to arithmetic overflow errors.
- underflow_error - Exception due to arithmetic underflow errors
- bad_alloc - Exception happens when memory allocation with new() fails.
- bad_cast - Exception happens when dynamic cast fails.
- bad_exception - Exception is specially designed to be listed in the dynamic-exception-specifier.
- bad_typeid - Exception thrown by typeid.
Example 1: C++ Program to demonstrate Exception Handling.
// program explains flow of execution of try/catch blocks.
#include <iostream>
using namespace std;
int main()
{
int x = -1;
cout << "Before try \n";
try {
cout << "Inside try \n";
if (x < 0) {
throw x;
cout << "After throw (Never executed) \n";
}
}
catch (int x) {
cout << "Exception Caught \n";
}
cout << "After Caught (Will be executed) \n";
return 0;
}
Output
Before try Inside try Exception Caught After catch (Will be executed)
Example 2: C++ Program to demonstrate Exception Handling.
There is a special catch block called ‘catch all’ catch(…) that can be used to catch all types of exceptions. For example, in the following program, an int is thrown as an exception, but there is no catch block for int, so catch(…) block will be executed.
#include <iostream>
using namespace std;
int main(){
try {
throw 10;
}
catch (char *excp) {
cout << "Caught " << excp;
}
catch (...) {
cout << "Default Exception \n";
}
return 0;
}
Output
Default Exception
Example 3: C++ Program to demonstrate Exception Handling
Implicit type conversion doesn’t happen for primitive types. For example, in the following program ‘a’ is not implicitly converted to int
#include <iostream>
using namespace std;
int main(){
try {
throw 'a';
}
catch (int x) {
cout << "Caught " << x;
}
catch (...) {
cout << "Default Exception \n";
}
return 0;
}
Output
Default Exception
Example 4: C++ Program to demonstrate Exception Handling
If an exception is thrown and not caught anywhere, the program terminates abnormally. For example, in the following program, a char is thrown, but there is no catch block to catch a char.
#include <iostream>
using namespace std;
int main(){
try {
throw 'a';
}
catch (int x) {
cout << "Caught " << x;
}
return 0;
}
Output
terminate called after throwing an instance of 'char' This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
Example 5: C++ Program to demonstrate Exception Handling
Unlike Java, in C++, all exceptions are unchecked. Compiler doesn’t check whether an exception is caught or not (See this for details). For example, in C++, it is not necessary to specify all uncaught exceptions in a function declaration. Although it’s a recommended practice to do so. For example, the following program compiles fine, but ideally signature of fun() should list unchecked exceptions.
#include <iostream>
using namespace std;
// Here we specify the exceptions that this function throws.
void fun(int *ptr, int x) throw(int *, int){
if (ptr == NULL) {
throw ptr;
}
if (x == 0) {
throw x;
// some functionality.
}
}
int main(){
try {
fun(NULL, 0);
}
catch (...) {
cout << "Caught exception from fun()";
}
return 0;
}
Output
Caught exception from fun()
Example 6: C++ Program to demonstrate Exception Handling
Unlike Java, in C++, all exceptions are unchecked. Compiler doesn’t check whether an exception is caught or not (See this for details). For example, in C++, it is not necessary to specify all uncaught exceptions in a function declaration. Although it’s a recommended practice to do so. For example, the following program compiles fine, but ideally signature of fun() should list unchecked exceptions.
#include <iostream>
using namespace std;
Class Exam{
public:
Exam() {cout << "Constructor of Exam \n"; }
~ Exam() {cout << "Destructor of Exam \n"; }
};
int main(){
try {
Exam e1;
throw 10;
}
catch (int i) {
cout << "Caught " << i << endl;
}
return 0;
}
Output
Constructor of Test Destructor of Test Caught 10
Example 7: C++ Program to demonstrate Exception Handling
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;
int main(){
try {
try {
throw 20;
}
catch (int n) {
cout << "Handle Partially ";
throw; // Re-throwing an exception
}
}
catch (int n) {
cout << "Handle remaining ";
}
return 0;
}
Output
Handle Partially Handle remaining
User-Defined Exceptions
The C++ std::exception class allows us to define objects that can be thrown as exceptions. This class has been defined in the
This function returns a null-terminated character sequence of type char *. We can overwrite it in derived classes to have an exception description.
Example 8: C++ Program to demonstrate User-Defined Exceptions
#include <iostream>
#include <exception>
using namespace std;
Class Excep : public exception{
Virtual const char* what() const throw()
{
return "Excep Occurred";
}
} newex;
int main(){
try {
throw newex;
}
catch (exception ex) {
cout << ex.what() << endl;
}
return 0;
}
Output
Excep Occurred
Advantage
It maintains the normal flow of the application. In such case, rest of the code is executed even after exception.
Next Tutorial
We hope that this tutorial helped you develop better understanding of the concept of Exception Handling in C++.
Keep Learning : )
In the next tutorial, you'll learn about C++ Multithreading
.