Exception Handling in C++

Exception handling is a mechanism to detect and respond to runtime errors — situations that occur while the program is running that the programmer cannot always predict. Instead of crashing the program, exceptions allow it to handle errors gracefully and continue or exit cleanly.

What is an Exception?

An exception is an unexpected event during program execution — like dividing by zero, accessing invalid memory, or failing to open a file. Without exception handling, such errors cause the program to crash abruptly.

The try-catch-throw Mechanism

  • try — Contains code that might throw an exception.
  • throw — Signals that an exception has occurred.
  • catch — Handles the exception.
#include <iostream>
using namespace std;

int main() {
    try {
        int a = 10, b = 0;
        if (b == 0)
            throw "Division by zero!";    // throw exception
        cout << a / b << endl;
    }
    catch (const char* msg) {            // catch exception
        cout << "Error: " << msg << endl;
    }
    cout << "Program continues..." << endl;
    return 0;
}

Output:

Error: Division by zero!
Program continues...

Throwing and Catching Different Types

try {
    throw 42;         // throw int
}
catch (int e) {
    cout << "Caught int: " << e << endl;
}

try {
    throw 3.14;       // throw double
}
catch (double e) {
    cout << "Caught double: " << e << endl;
}

Output:

Caught int: 42
Caught double: 3.14

Multiple Catch Blocks

Multiple catch blocks can handle different exception types:

void processInput(int type) {
    if (type == 1) throw 100;
    if (type == 2) throw "File not found";
    if (type == 3) throw 3.14;
}

int main() {
    for (int i = 1; i <= 3; i++) {
        try {
            processInput(i);
        }
        catch (int e)         { cout << "Int error: "    << e << endl; }
        catch (const char* e) { cout << "String error: " << e << endl; }
        catch (double e)      { cout << "Double error: " << e << endl; }
    }
    return 0;
}

Output:

Int error: 100
String error: File not found
Double error: 3.14

Catch-All Handler

A catch block with ... catches any type of exception:

try {
    throw "Unknown error";
}
catch (...) {
    cout << "An unknown exception occurred." << endl;
}

Standard Exception Classes

C++ provides a hierarchy of standard exception classes in the <stdexcept> header:

Exception ClassMeaning
std::exceptionBase class for all standard exceptions
std::runtime_errorRuntime errors
std::logic_errorLogic errors in the program
std::out_of_rangeAccess beyond valid range
std::invalid_argumentInvalid argument passed to function
std::overflow_errorArithmetic overflow
#include <iostream>
#include <stdexcept>
using namespace std;

int main() {
    try {
        throw runtime_error("Something went wrong!");
    }
    catch (const exception &e) {
        cout << "Exception: " << e.what() << endl;
    }
    return 0;
}

Output:

Exception: Something went wrong!

Custom Exception Classes

Custom exception classes can be created by inheriting from std::exception:

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

class NegativeAgeException : public exception {
public:
    const char* what() const noexcept override {
        return "Age cannot be negative!";
    }
};

void setAge(int age) {
    if (age < 0) throw NegativeAgeException();
}

int main() {
    try {
        setAge(-5);
    }
    catch (const NegativeAgeException &e) {
        cout << "Custom Exception: " << e.what() << endl;
    }
    return 0;
}

Output:

Custom Exception: Age cannot be negative!

Re-throwing Exceptions

void process() {
    try {
        throw runtime_error("Original error");
    }
    catch (const exception &e) {
        cout << "Partial handling: " << e.what() << endl;
        throw;   // re-throw to outer handler
    }
}

int main() {
    try {
        process();
    }
    catch (const exception &e) {
        cout << "Final handling: " << e.what() << endl;
    }
    return 0;
}

Key Takeaways

  • Exception handling prevents programs from crashing on runtime errors.
  • The try block contains risky code; throw signals an error; catch handles it.
  • Multiple catch blocks can handle different exception types.
  • Use catch(...) as a fallback for any unhandled exception type.
  • Inherit from std::exception to create custom, meaningful exception classes.

Leave a Comment

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