C++ Multiple Catch Blocks

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 first catch block.
  • If the user enters 2, a custom exception MyException is thrown and caught by the second catch block.
  • If the user enters 3, a string exception is thrown and caught by the third catch 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 and InvalidOperationException classes inherit from std::exception and override the what method to return custom error messages.
  • The divide function throws a DivisionByZeroException if the divisor is zero.
  • The calculate function performs the requested operation and throws an InvalidOperationException for invalid operations.
  • The main function captures these exceptions using multiple catch 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top