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.14Multiple 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.14Catch-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 Class | Meaning |
|---|---|
std::exception | Base class for all standard exceptions |
std::runtime_error | Runtime errors |
std::logic_error | Logic errors in the program |
std::out_of_range | Access beyond valid range |
std::invalid_argument | Invalid argument passed to function |
std::overflow_error | Arithmetic 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
tryblock contains risky code;throwsignals an error;catchhandles it. - Multiple catch blocks can handle different exception types.
- Use
catch(...)as a fallback for any unhandled exception type. - Inherit from
std::exceptionto create custom, meaningful exception classes.
