Tutorial: Throwing and Catching Exceptions in C++

Exceptions are a powerful mechanism in C++ for handling errors and exceptional situations during program execution. By throwing and catching exceptions, you can control the flow of your program and handle errors gracefully. This tutorial will guide you through the process of throwing and catching exceptions in C++.

Throwing Exceptions

In C++, you can throw an exception when an error or exceptional condition occurs. To throw an exception, you can use the throw keyword followed by an expression or object of an appropriate exception type. Here's an example of throwing an exception when encountering an error:

#include <iostream>

void processInput(int input) {
  if (input < 0) {
    throw "Invalid input: input cannot be negative";
  }
  std::cout << "Valid input: " << input << std::endl;
}

int main() {
  try {
    int userInput;
    std::cout << "Enter a positive number: ";
    std::cin >> userInput;
    processInput(userInput);
  } catch (const char* errorMessage) {
    std::cerr << "Exception caught: " << errorMessage << std::endl;
  }

  return 0;
}

Catching Exceptions

In C++, exceptions can be caught using try-catch blocks. The try block contains the code that may throw an exception, while the catch block handles the exception if one is thrown. Here's an example of catching an exception thrown in the previous code snippet:

#include <iostream>

void processInput(int input) {
  if (input < 0) {
    throw "Invalid input: input cannot be negative";
  }
  std::cout << "Valid input: " << input << std::endl;
}

int main() {
  try {
    int userInput;
    std::cout << "Enter a positive number: ";
    std::cin >> userInput;
    processInput(userInput);
  } catch (const char* errorMessage) {
    std::cerr << "Exception caught: " << errorMessage << std::endl;
  }

  return 0;
}

Common Mistakes:

  • Not catching exceptions at the appropriate level, resulting in unexpected program termination.
  • Throwing exceptions of incorrect types or not providing sufficient information in the exception object, making it difficult to handle and diagnose errors.
  • Using exceptions as a substitute for proper error handling, leading to inefficient program execution and unexpected behavior.

FAQs:

  1. Q: What happens if an exception is thrown but not caught?

    A: If an exception is thrown but not caught, the program will terminate abruptly and the std::terminate function will be called.

  2. Q: Can I define my own exception types?

    A: Yes, you can define your own exception types by creating classes that derive from std::exception or its derived classes.

  3. Q: Can I catch multiple types of exceptions in a single catch block?

    A: Yes, you can catch multiple types of exceptions in a single catch block by using the ellipsis (...) or by specifying multiple exception types separated by the logical OR operator (|).

  4. Q: When should I use exceptions versus return codes?

    A: Exceptions are generally recommended for handling exceptional situations, while return codes are suitable for normal program flow and expected errors.

  5. Q: Should I always catch exceptions by reference?

    A: It is generally recommended to catch exceptions by const reference (const std::exception&) to avoid object slicing and unnecessary copying.

Summary:

Throwing and catching exceptions in C++ allows you to handle errors and exceptional situations in a controlled manner. By throwing exceptions when encountering errors and catching them at appropriate levels, you can provide meaningful error messages and take necessary actions to handle exceptional conditions. It's important to avoid common mistakes, such as not catching exceptions or throwing exceptions of incorrect types. With proper exception handling, you can improve the robustness and reliability of your C++ programs.