Back to C++
2026-03-295 min read

Exception Handling

Learn Exception Handling step by step with clear examples and exercises.

Why This Matters

Exception handling is a fundamental aspect of C++ programming that plays a crucial role in managing runtime errors and abnormal conditions, ensuring your program can continue running smoothly even when faced with unexpected issues. In this lesson, we will delve into the world of exception handling, explaining its importance, prerequisites, core concepts, worked examples, common mistakes, practice questions, and frequently asked questions.

The Importance of Exception Handling

Exception handling is essential for maintaining program stability by preventing unexpected termination. It allows you to handle errors gracefully, providing a chance to recover from abnormal conditions or display meaningful error messages to the user. In real-world applications, exception handling can help catch and resolve issues that may occur during runtime, making your code more robust and reliable.

Prerequisites

To fully understand exception handling in C++, you should be familiar with:

  1. Basic C++ syntax (variables, operators, loops, functions)
  2. Object-oriented programming concepts (classes, objects, inheritance)
  3. Standard Template Library (STL) containers and iterators
  4. File I/O operations
  5. Understanding the difference between checked and unchecked exceptions
  6. Familiarity with exception classes like runtime_error, logic_error, out_of_range, and invalid_argument

Core Concept

Exception Hierarchy

C++ provides a hierarchy of exception classes that help manage errors effectively. The base class for all exceptions is std::exception, which includes important member functions such as what() and what_cstr(). Derived from this base, you'll find several standard exceptions like runtime_error, logic_error, out_of_range, and invalid_argument.

Exception Classes

  • std::exception: Base class for all exceptions in C++. It provides a common interface with member functions like what() and what_cstr().
  • runtime_error: Derived from std::exception, this exception is used to indicate runtime errors, such as division by zero or invalid memory access.
  • logic_error: Also derived from std::exception, this exception is used for logic errors, such as an out-of-range index or an invalid argument.
  • out_of_range: A specific type of logic_error that indicates an out-of-range condition, like accessing an array element beyond its bounds.
  • invalid_argument: Another specific type of logic_error that represents an invalid or illogical argument passed to a function.

try-catch Blocks

The core of exception handling in C++ involves the use of a try block to enclose code that might throw an exception, along with one or more catch blocks to handle those exceptions if they occur. Here's a basic example:

#include <iostream>
using namespace std;

int main() {
int n = 10;
int m = 0;

try {
if (m == 0) throw "Division by zero";
cout << "Answer: " << n / m;
} catch (const char *msg) {
cerr << "Error: " << msg;
}

return 0;
}

In this example, if m is zero, the program throws a string exception, which is caught by the corresponding catch block and displayed as an error message.

Rethrowing Exceptions

You can rethrow an exception in C++ using the throw; statement to allow the exception to be caught by a higher-level catch block. This can be useful when handling exceptions within functions or constructors.

Worked Example

Let's walk through a more complex example that demonstrates exception handling in action:

#include <iostream>
#include <stdexcept>
using namespace std;

class Person {
public:
Person(int age) {
if (age < 0) throw invalid_argument("Age must be non-negative");
_age = age;
}

private:
int _age;
};

int main() {
try {
Person p(-1);
} catch (const invalid_argument &e) {
cerr << e.what() << endl;
}

return 0;
}

In this example, the Person class has a constructor that checks if the age is valid (i.e., non-negative). If not, it throws an invalid_argument exception, which is caught by the catch block in the main function and displayed as an error message.

Common Mistakes

1. Not Properly Using try-catch Blocks

Ensure that your try block contains the code that might throw an exception, and place the appropriate catch blocks to handle those exceptions.

2. Improper Exception Handling in Constructors

Constructor functions cannot be called within a try block, as they are used to initialize objects. Instead, consider using a separate initialization function or rethrowing the exception.

3. Not Catching Specific Exceptions

If you want to handle specific exceptions, make sure to catch them explicitly. For example:

catch (runtime_error &e) {
cerr << "Runtime error: " << e.what() << endl;
}

4. Not Properly Rethrowing Exceptions

When rethrowing an exception, ensure that you use throw; to pass the exception on to a higher-level catch block.

Practice Questions

  1. Write a function that checks if a number is prime, and throw an exception if the input is negative or less than 2.
  2. Create a custom exception class to handle invalid file names when reading from files.
  3. Modify the Person example to use a try-catch block within the constructor itself.
  4. Write a function that calculates the factorial of a number, and throw an exception if the input is negative or greater than 100.

FAQ

1. What happens if an exception is not caught?

If an exception is not caught, the program will terminate abruptly with an error message.

2. Can I create my own custom exceptions in C++?

Yes! You can define your own exception classes by deriving from std::exception or one of its derived classes.

3. Is it possible to rethrow an exception in C++?

Yes, you can use the throw; statement to rethrow an exception in C++. This allows the exception to be caught by a higher-level catch block.

4. Can I throw exceptions from within a loop or function that might be called multiple times?

Yes, but it's important to consider the performance implications of throwing exceptions frequently and handle them appropriately to avoid excessive overhead.

Exception Handling | C++ | XQA Learn