Exception Handling in C++

Exception handling in C++ is a mechanism to handle runtime errors in a way that maintains normal program flow. In C++, exceptions are used to handle errors or other exceptional conditions in a program without disrupting the program’s execution.

C++ provides three key components for exception handling:

  • try block – Code that may throw an exception is placed inside the try block.
  • throw keyword – An exception is thrown using the throw keyword.
  • catch block – Exceptions thrown from the try block are handled by the catch block.

Here is a simple example:

Basic Syntax:

#include <iostream>
#include <stdexcept> // For standard exceptions

int main() {
try {
// Code that may throw an exception
int x = 10;
int y = 0;

if (y == 0) {
throw std::invalid_argument(“Division by zero”);
}

int result = x / y; // This line will not execute due to the exception
std::cout << “Result: ” << result << std::endl;

} catch (const std::invalid_argument &e) {
// Handling the exception
std::cout << “Error: ” << e.what() << std::endl;
}

return 0;
}

Explanation:

  1. try block: The code inside the try block attempts to perform a division. If a division by zero occurs, an exception is thrown using throw.

  2. throw: The throw statement creates an exception object. In this case, we throw an std::invalid_argument exception with a message that division by zero occurred.

  3. catch block: The catch block handles the exception thrown in the try block. It catches exceptions of type std::invalid_argument and prints the error message using the what() method.

Exception Handling Flow:

  • If an exception is thrown, the normal flow of control is interrupted, and the program jumps to the corresponding catch block.
  • If no exception occurs, the catch block is skipped, and the program continues executing after the try-catch block.

Multiple catch blocks:

You can have multiple catch blocks to handle different types of exceptions:

#include <iostream>
#include <stdexcept>

int main() {
try {
int x = 10;
int y = 0;

if (y == 0) {
throw std::runtime_error(“Runtime error: Division by zero”);
}

int result = x / y;
std::cout << “Result: ” << result << std::endl;

} catch (const std::runtime_error &e) {
std::cout << “Caught a runtime error: ” << e.what() << std::endl;
} catch (const std::exception &e) {
std::cout << “Caught a general exception: ” << e.what() << std::endl;
}

return 0;
}

Explanation:

  • The first catch block handles exceptions of type std::runtime_error.
  • The second catch block is a more general catch that handles any other exceptions derived from std::exception.

Standard Exception Classes:

C++ provides several standard exception classes, which are part of the std namespace:

  • std::exception: The base class for all standard exceptions.
  • std::runtime_error: Represents errors that are detected during runtime.
  • std::logic_error: Represents errors in program logic (e.g., invalid arguments).
  • std::overflow_error, std::underflow_error: For overflow or underflow conditions.
  • std::bad_alloc: Thrown when memory allocation fails.

Re-throwing Exceptions:

You can re-throw an exception from a catch block if you want it to be handled further up the call stack:

try {
// Some code that might throw
} catch (…) {
// Handle exception, then rethrow it
throw; // Re-throws the current exception
}

Conclusion:

Exception handling in C++ allows you to handle errors gracefully by catching exceptions and ensuring the program continues running smoothly. By using try, throw, and catch, you can manage errors more effectively and write more robust programs.