Exception handling plays a crucial role in ensuring the reliability of software systems. It allows developers to gracefully respond to unexpected situations that may arise during program execution. The robust exception handling mechanism in C++ empowers developers to effectively manage different types of exceptions. This article delves into the concept of multiple catch statements in C++, illustrating how they can be employed to handle diverse exceptional scenarios.
The C++ try, catch, and throw keywords are implemented to manage exceptions. When a special situation occurs within a try block, a corresponding catch block is executed to manage the exception. Exceptions are triggered by employing the throw keyword, and catch blocks specify the appropriate way to deal with specific exceptions.
The Need of Several Catch Blocks:
A program might encounter different types of exceptions regularly, each requiring a specific response. In such cases, having multiple catch blocks proves to be highly beneficial. It is advantageous to have several catch blocks, each tailored to handle a specific type of exception, rather than relying on a single catch block to manage all exceptions.
Syntax:
It has the following syntax:
try {
// Code that may throw exceptions
} catch (ExceptionType1 e) {
// Handle ExceptionType1
} catch (ExceptionType2 e) {
// Handle ExceptionType2
} catch (ExceptionType3 e) {
// Handle ExceptionType3
} // ...
Example 1:
Handling invalid input with divide-by-zero
Let's consider a basic scenario where we perform the division operation between two numbers, while ensuring proper handling of two specific exceptions: division by zero and incorrect input values.
#include <iostream>
int main() {
int dividend, divisor;
try {
std::cout << "Enter dividend: ";
std::cin >> dividend;
std::cout << "Enter divisor: ";
std::cin >> divisor;
if (divisor == 0)
throw "Division by zero is not allowed.";
double result = static_cast<double>(dividend) / divisor;
std::cout << "Result: " << result << std::endl;
} catch (const char* message) {
std::cerr << "Error: " << message << std::endl;
} catch (...) {
std::cerr << "Unknown exception occurred." << std::endl;
}
return 0;
}
Output
Enter dividend: 10
Enter divisor: 0
Error: Division by zero is not allowed.
Enter dividend: 10
Enter divisor: a
Unknown exception occurred.
Explanation:
In this instance, we utilize two catch blocks: the first one is for managing exceptions related to const char* type (specifically for divide-by-zero situations), while the second one is for dealing with any other exceptions (typically for incorrect input scenarios).
Example 2:
Custom Exception Classes Handling:
By deriving from the std::exception class, custom exception classes can be defined in C++. Let's design a unique exception type and demonstrate how to manage it alongside standard exceptions.
#include <iostream>
#include <stdexcept>
class MyException : public std::exception {
public:
const char* what() const noexcept override {
return "Custom Exception: Something went wrong.";
}
};
int main() {
try {
// Simulate a custom exception
if (true)
throw MyException();
// Simulate a standard exception
else
throw std::runtime_error("Standard Exception: Something went wrong.");
} catch (const MyException& e) {
std::cerr << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Output
Custom Exception: Something went wrong.
Explanation:
In this instance, we encounter two catch blocks, one designed for the specific exception MyException and another for the general exception std::exception.
Conclusion:
In C++, multiple catch statements provide a powerful approach to effectively manage different types of exceptions. By structuring catch blocks to correspond with specific exception types, we can enhance the program's dependability and ease of maintenance. It is essential for every C++ developer to grasp the concept and application of multiple catch blocks, as this practice contributes to the development of robust and fault-tolerant programs.