Introduction
In C++, multiple catch blocks allow you to handle different types of exceptions thrown by a try
block. Each catch block is designed to handle a specific type of exception. When an exception is thrown, the type of the exception is compared against each catch block in order. The first catch block that matches the type of the exception is executed.
Syntax
The syntax for using multiple catch blocks is straightforward. After the try
block, you can specify multiple catch
blocks, each handling a different type of exception.
try {
// Code that may throw an exception
} catch (exception_type1 e1) {
// Handle exception of type exception_type1
} catch (exception_type2 e2) {
// Handle exception of type exception_type2
} catch (...) {
// Handle any other type of exception
}
Example: Handling Different Types of Exceptions
Let’s look at an example where we handle different types of exceptions using multiple catch blocks.
Code Example
#include <iostream>
#include <exception>
using namespace std;
class MyException : public exception {
public:
const char* what() const noexcept override {
return "My custom exception occurred";
}
};
int main() {
try {
int choice;
cout << "Enter 1 to throw int, 2 to throw MyException, 3 to throw const char*: ";
cin >> choice;
if (choice == 1) {
throw 10; // Throw an integer
} else if (choice == 2) {
throw MyException(); // Throw a custom exception
} else if (choice == 3) {
throw "A string exception"; // Throw a string
} else {
cout << "No exception thrown" << endl;
}
} catch (int e) {
cout << "Integer exception caught: " << e << endl;
} catch (const MyException& e) {
cout << "Custom exception caught: " << e.what() << endl;
} catch (const char* e) {
cout << "String exception caught: " << e << endl;
} catch (...) {
cout << "An unknown exception was caught" << endl;
}
return 0;
}
Output
Enter 1 to throw int, 2 to throw MyException, 3 to throw const char*: 1
Integer exception caught: 10
Explanation
- The
try
block contains code that may throw different types of exceptions based on user input. - If the user enters
1
, an integer exception is thrown and caught by the firstcatch
block. - If the user enters
2
, a custom exceptionMyException
is thrown and caught by the secondcatch
block. - If the user enters
3
, a string exception is thrown and caught by the thirdcatch
block. - Any other type of exception is caught by the last
catch
block that uses...
(ellipsis), which is a catch-all handler.
Practical Example: Handling Different Types of Errors
Let’s create an example where we handle different types of errors in a more practical scenario, such as a simple calculator that can throw different types of exceptions.
Code Example
#include <iostream>
#include <exception>
using namespace std;
class DivisionByZeroException : public exception {
public:
const char* what() const noexcept override {
return "Division by zero error!";
}
};
class InvalidOperationException : public exception {
public:
const char* what() const noexcept override {
return "Invalid operation error!";
}
};
double divide(double a, double b) {
if (b == 0) {
throw DivisionByZeroException();
}
return a / b;
}
double calculate(double a, double b, char op) {
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return divide(a, b);
default:
throw InvalidOperationException();
}
}
int main() {
try {
double num1, num2;
char op;
cout << "Enter two numbers: ";
cin >> num1 >> num2;
cout << "Enter an operation (+, -, *, /): ";
cin >> op;
double result = calculate(num1, num2, op);
cout << "Result: " << result << endl;
} catch (const DivisionByZeroException& e) {
cout << "Error: " << e.what() << endl;
} catch (const InvalidOperationException& e) {
cout << "Error: " << e.what() << endl;
} catch (const exception& e) {
cout << "An unknown error occurred: " << e.what() << endl;
}
return 0;
}
Output
Enter two numbers: 10 0
Enter an operation (+, -, *, /): /
Error: Division by zero error!
Explanation
- The
DivisionByZeroException
andInvalidOperationException
classes inherit fromstd::exception
and override thewhat
method to return custom error messages. - The
divide
function throws aDivisionByZeroException
if the divisor is zero. - The
calculate
function performs the requested operation and throws anInvalidOperationException
for invalid operations. - The
main
function captures these exceptions using multiplecatch
blocks, each tailored to handle a specific type of exception, and prints the appropriate error message.
Conclusion
Multiple catch blocks in C++ allow you to handle different types of exceptions in a controlled manner. By specifying multiple catch
blocks, each tailored to a specific type of exception, you can ensure that your program responds appropriately to various errors. This improves the robustness and maintainability of your code. Understanding and effectively using multiple catch blocks is essential for writing reliable and error-resistant C++ programs.