Exception handling is very crucial in C++. It provides a mechanism for managing and responding to runtime errors. Instead of allowing errors to crash the program or lead to unpredictable behavior, exception handling allows you to detect, handle, and recover from errors. It helps to improve the stability and user experience of our applications. In this blog, we will discuss about Exception Handling in C++.
A C++ exception is an object representing an error or unexpected condition that occurs during program execution. It is thrown using the throw keyword and handled using try-and-catch blocks to manage errors gracefully.
Types of Exceptions in C++
There are two types of Exceptions in C++
Synchronous Exceptions: These occur during the execution of a specific code statement, such as invalid operations like division by zero or accessing invalid memory. They are directly related to the code that caused them.
Asynchronous Exceptions: These are triggered by external events or conditions, such as hardware interrupts or signals, rather than by specific code statements. They can occur independently of the program’s current execution flow.
Exception Handling keywords in C++
These are three keywords that are used to resolve exceptions in C++.
1. Try in C++
A try block encloses code that may throw exceptions. It allows you to define a section of code where errors might occur and provides a mechanism to handle those errors using catch blocks.
2. Catch in C++
A catch block follows a try block and handles exceptions thrown within it. It specifies the type of exception it can handle and contains code to manage the error, preventing program termination.
3. Throw in C++
The throw keyword is used to signal the occurrence of an exception. It transfers control to the nearest catch block that matches the type of the thrown exception, enabling error handling.
There is one try statement in the above syntax and many catch statements. The Exception_name is the name of the exception to be caught. The exception_1,exception_2, and exception_N are defined names. They are referring to the exceptions.
Why is Exception Handling used in C++?
The main advantages of exception handling over traditional error handling are given below.
To distinguish the error handling code from the normal code: In traditional error handling, we always use if and else statements to handle the errors. These traditional error handling codes get mixed up with the normal code. This makes code less readable and maintainable. We use exception handling over traditional error handling to get rid of these problems.
A function can handle any exception they choose: In C++, a function can identify the exceptions that it throws with the help of the throw keyword. The caller of this function will handle the uncaught exception either by specifying it again or catching it.
Grouping of Error Types: We use exception handling to create a hierarchy of exception objects, group exceptions in namespaces or classes, categorize them according to types.o
Example of Exception Handling in C++
C++
C++
#include<bits/stdc++.h> using namespace std; int main() { try { int age=16; int voting_age=18; if (age>=voting_age) { cout<< "You are eligible for voting."; } else { throw "You are not eligible for voting."; } } catch (const char* msg) { cout<< "For voting, You must be at least 18 years old." <<endl; cout<<msg; } return 0; }
You can also try this code with Online C++ Compiler
All the standard exceptions are defined in the <exception> class. These are described below:
Exception
Description
std::bad_exception
It is used for handling unexpected exceptions in C++ programs.
std::exception
An exception and parent class of all the standard exceptions of C++.
std::bad_alloc
This exception occurs when the new operator fails to allocate the requested space.
std::domain_error
This is an exception that is thrown when a mathematically invalid domain is used.
std::bad_typeid
This is an exception thrown by typeid.
std::bad_cast
This exception is thrown by dynamic_cast.
std::invalid_argument
This is an exception thrown for using invalid arguments.
std::length_error
This is an exception thrown after creating a big std::string.
std::out_of_range
This exception is thrown by the 'at' method.
std::logic_error
This is the type of exception that theoretically can be detected by reading the code.
std::overflow_error
This is an exception that is thrown after the occurrence of a mathematical overflow.
std::range_error
This is an exception that is thrown when you attempt to store an out-of-range value.
std::runtime_error
This is the type of exception that cannot be detected via reading the code.
std::underflow_error
This is an exception thrown after the occurrence of mathematical underflow.
User-defined Exceptions in C++
Users can define their own exceptions by inheriting and overriding the exception class functionality. the given example shows how you can use std::exception class to implement your own exception in the standard way-
C++
C++
#include<bits/stdc++.h> #include<exception> using namespace std; class Divisor_zero_exception: public exception { public: const char *what()const throw() { return "The divisor can not be zero."; } }; int main() { try { int a=15; int b=0; if (b == 0) { Divisor_zero_exception e; throw e; } else { cout<<"the value of a/b="<<a/b<<endl; } } catch(exception& ex) { cout << ex.what()<<endl; } return 0; }
You can also try this code with Online C++ Compiler
What are the principles of exception handling in C++?
The principles of exception handling in C++ include separating error-handling code from regular code using try and catch blocks, using the throw keyword to signal errors, and ensuring that exceptions are caught and handled properly to maintain program stability and reliability.
Can a try block be nested under another try block?
Yes, a try block can be nested within another try block. This allows for more granular exception handling, where different levels of code can handle exceptions separately. Each nested try block can have its own corresponding catch blocks to manage specific errors.
What are the limitations of exception handling in C++?
Limitations of exception handling in C++ include potential performance overhead, complexity in managing multiple exceptions, and the need for careful design to avoid unhandled exceptions. Additionally, exceptions can't be used for flow control and require proper cleanup of resources to prevent leaks.
Conclusion
In this article, we have discussed Exception Handling in C++. It is a powerful feature that enhances the robustness and reliability of your programs by allowing graceful error management. By using try, catch, and throw, you can handle runtime errors effectively and maintain clean, readable code.