Exception Handling in C++
What is Exception handling in C++?
- Exception handling in C++ is a mechanism that allows you to deal with unexpected or exceptional situations that may occur during the execution of a program.
- These situations are often referred to as "exceptions."
Exception handling in C++ Syntax
C++, exception handling is done using the try, catch, and throw keywords. Here's the syntax for exception handling:
Throwing an Exception
To throw an exception, you use the throw keyword followed by an exception object:
1throw MyException("An error occurred");
C++ try-catch Block
The try block is used to enclose a section of code where an exception might be thrown. Afterward, there are one or more catch blocks.
1try {
2// Code that might throw an exception
3} catch (ExceptionType1 &e1) {
4// Handle ExceptionType1
5} catch (ExceptionType2 &e2) {
6// Handle ExceptionType2
7} catch (...) {
8// Handle any other exception
9}
- In this example, we have a try block with multiple catch blocks.
- If an exception of type ExceptionType1 is thrown, it will be captured by the initial catch block.
- If it's ExceptionType2, it will be caught by the second catch block.
- The ellipsis (...) in the last catch block is a generic catch that can catch any type of exception.
Catching Exception
- Every catch block specifies the particular type of exception it can handle.
- When an exception is thrown, the program checks each catch block to see if the thrown exception matches the specified type.
- If it does, the corresponding catch block is executed.
Rethrowing an Exception
- Inside a catch block, you can rethrow the same exception using throw.
- This allows the exception to be caught and handled by an outer try-catch block or propagated up the call stack.
1try {
2// Code that might throw an exception
3} catch (ExceptionType &e) {
4// Handle the exception
5throw; // Rethrow the exception
6}
Exception Classes
- Exception types can be built-in types or user-defined classes.
- User-defined exception classes should typically be derived from std::exception or a related base class.
1class MyException : public std::exception {
2public:
3const char* what() const noexcept {
4return "My custom exception occurred";
5}
6};
Exception Handling in C++ Example
Example of exception handling in C++:
1#include <iostream>
2using namespace std;
3
4// Custom exception class derived from std::exception
5class MyException : public exception {
6public:
7 const char* what() const noexcept {
8 return "My custom exception occurred";
9 }
10};
11
12int main() {
13 try {
14 int x = 10, y = 0;
15
16 if (y == 0) {
17 // Throwing an exception of type MyException
18 throw MyException();
19 }
20
21 int result = x / y;
22 cout << "Result: " << result << endl;
23 } catch (const MyException &e) {
24 // Catching and handling MyException
25 cout << "Custom Exception Caught: " << e.what() << endl;
26 } catch (const exception &e) {
27 // Catching any other exception derived from std::exception
28 cout << "Standard Exception Caught: " << e.what() << endl;
29 } catch (...) {
30 // Catching any other type of exception
31 cout << "Unknown Exception Caught" << endl;
32 }
33
34 return 0;
35}
- We define a custom exception class MyException that is derived from std::exception. It overrides the what() function to provide a custom error message.
- In the main function, we attempt to divide x by y. If y is 0, we throw a MyException.
Types of exception in C++
- std::exception
- std::runtime_error
- std::logic_error
- std::invalid_argument
- std::out_of_range
- std::overflow_error
- std::underflow_error
- std::bad_alloc
- std::bad_typeid
- std::future_error
std::exception
std::exception is the base class for all standard C++ exceptions. It provides a what() function that returns a descriptive error message.
std::runtime_error
std::runtime_error is typically used to represent errors that can occur during runtime and are not easily predictable.
std::logic_error
std::logic_error is used for errors that are generally caused by a mistake in the program's logic.
std::invalid_argument
This exception is thrown when a function receives an argument of an inappropriate value.
std::out_of_range
std::out_of_range is thrown by functions that have a defined range, such as arrays or containers, and the argument provided is outside that range.
std::overflow_error
This exception is thrown when arithmetic overflow occurs.
std::underflow_error
std::underflow_error is thrown when arithmetic underflow occurs, which happens when calculations result in values too close to zero to be represented accurately. It's another subclass of std::runtime_error.
std::bad_alloc
This exception is thrown when the new operator fails to allocate memory due to insufficient memory resources.
std::bad_typeid
This exception is thrown by the typeid operator when it cannot identify the type of an object. It's useful for handling errors related to type identification.
std::future_error
std::future_error is thrown when an error occurs in a std::future or std::shared_future operation.
It's worth noting that you can also create your own custom exceptions by subclassing std::exception or one of its derived classes.
Specifying exceptions for a function
- You can specify the types of exceptions a function might throw using the throw keyword in the function declaration.
- Now, let's provide some simple examples:
1#include <iostream>
2using namespace std;
3
4int main() {
5 try {
6 int x = 10, y = 0;
7 if (y == 0) {
8 throw runtime_error("Divide by zero error");
9 }
10 int result = x / y;
11 cout << "Result: " << result << endl;
12 } catch (runtime_error &e) {
13 cout << "Error: " << e.what() << endl;
14 }
15
16 return 0;
17}
- In this example, we're attempting to divide x by y.
- If y is 0, it will throw a runtime_error with the message "Divide by zero error".
- This exception will be caught in the catch block, and the error message will be printed.
Benefits of exception handling
- Separation of Error Handling Code:
- Exception handling allows you to separate the code that detects errors from the code that handles them.
- Graceful Recovery from Errors:
- Exceptions provide a mechanism for gracefully recovering from errors.
- Robustness and Reliability:
- Exception handling improves the robustness and reliability of your code.
Conclusion
Exception handling in C++ is a powerful mechanism for managing errors and exceptional situations in a program.