C++ Exceptions
C++ exceptions handle errors that a function cannot deal with itself. The function throws an exception, and code higher up catches it with try and catch, keeping error handling separate from normal logic.
try, throw and catch
#include <iostream>
#include <stdexcept>
double divide(double a, double b) {
if (b == 0) throw std::invalid_argument("division by zero");
return a / b;
}
int main() {
try {
std::cout << divide(10, 2) << '\n';
std::cout << divide(1, 0) << '\n';
} catch (const std::invalid_argument& e) {
std::cout << "Error: " << e.what() << '\n';
}
}5 Error: division by zero
Standard Exception Types
- std::exception: base of all standard exceptions
- std::invalid_argument and std::out_of_range: bad inputs or indexes
- std::runtime_error: errors detected at runtime
- std::bad_alloc: memory allocation failed
- Catch by const reference to avoid copying and slicing.
Catching Library Exceptions
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
try {
std::cout << v.at(10) << '\n';
} catch (const std::out_of_range&) {
std::cout << "Index out of range\n";
} catch (const std::exception& e) {
std::cout << "Other error: " << e.what() << '\n';
}
}Index out of range
Custom Exceptions
#include <iostream>
#include <stdexcept>
class InsufficientFunds : public std::runtime_error {
public:
InsufficientFunds() : std::runtime_error("not enough balance") {}
};
int main() {
try {
throw InsufficientFunds{};
} catch (const std::exception& e) {
std::cout << e.what() << '\n';
}
}not enough balance
noexcept
Mark functions that never throw as noexcept. It documents intent and allows optimizations, for example std::vector moves elements faster when their move constructor is noexcept.
Frequently asked questions
Why catch exceptions by const reference?
Catching by reference avoids copying and keeps the derived type, so virtual functions like what() return the right message. const shows you will not modify it.
What happens if an exception is not caught?
The program calls std::terminate and ends abnormally. Catch exceptions at a level where you can handle them meaningfully.
Are C++ exceptions slow?
Modern implementations have almost zero cost when no exception is thrown. Throwing is relatively expensive, so use exceptions for exceptional cases, not normal control flow.