Exception Handling in C++ (try, catch, throw, std::exception)
🟡 Intermediate
📖 Definition
Exception Handling is a mechanism in C++ that isolates runtime error detection from error recovery logic. When an abnormal runtime situation occurs (such as division by zero, invalid input, or out-of-memory errors), the program throws an exception. The execution control jumps to a matching catch block wrapped in a try block.
🇮🇳 Hindi Explanation
Runtime errors (jaise file na milna, ya zero se divide karna) ko handle karne ke liye try-catch blocks ka use hota hai:
try: Us code ko wrap karta hai jisme error aane ki sambhavna ho.throw: Anomaly ya error milne par exception throw karta hai.catch: Thrown exception ko catch karta hai aur program ko crash hone se bachata hai.
🚩 Marathi Explanation
Runtime errors mule program crash hou naye mhanun Exception Handling cha vapar ke la jato.
try: Zyathaat error yeu shakto to codetryblock madhye thevla jato.throw: Error aalyas exception feknyasathi (throw).catch: Anomaly/Error catch karun program surakshitapane saambhalnyasathi.
📝 Syntax & Exception Hierarchy
try {
// Code that might throw an exception
if (errorCondition) {
throw std::runtime_error("Error description");
}
} catch (const std::runtime_error& e) {
// Handle specific runtime_error
std::cerr << "Caught Error: " << e.what() << std::endl;
} catch (const std::exception& e) {
// Fallback handler for standard exceptions
} catch (...) {
// Catch-all handler for unknown non-standard exceptions
}
💡 Practical Example
#include <iostream>
#include <stdexcept> // Standard exceptions header
#include <string>
// Custom Function that validates and divides numbers
double divide(double numerator, double denominator) {
if (denominator == 0.0) {
throw std::invalid_argument("Division by Zero is undefined!");
}
return numerator / denominator;
}
// Custom Function that validates user age
void verifyAge(int age) {
if (age < 0) {
throw std::out_of_range("Age cannot be negative!");
}
if (age < 18) {
throw std::runtime_error("Access Denied: User is under 18.");
}
std::cout << "Access Granted. Welcome!" << std::endl;
}
int main() {
std::cout << "--- 1. SAFE DIVISION DEMO ---" << std::endl;
try {
std::cout << "10 / 2 = " << divide(10.0, 2.0) << std::endl;
std::cout << "10 / 0 = " << divide(10.0, 0.0) << std::endl; // Throws exception!
} catch (const std::invalid_argument& e) {
std::cerr << "[CAUGHT ERROR] " << e.what() << std::endl;
}
std::cout << "\n--- 2. AGE VERIFICATION DEMO ---" << std::endl;
try {
verifyAge(15);
} catch (const std::out_of_range& e) {
std::cerr << "[OUT OF RANGE] " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "[EXCEPTION] " << e.what() << std::endl;
}
std::cout << "\nProgram execution continued safely without crashing!" << std::endl;
return 0;
}
🔍 Code Breakdown
throw std::invalid_argument(...): Creates an exception object containing an error message string (.what()).catch (const std::exception& e): Catches any exception derived fromstd::exceptionby const reference to avoid slice copying.e.what(): Returns the C-style string error message stored in the exception object.
👀 Output
--- 1. SAFE DIVISION DEMO ---
10 / 2 = 5
[CAUGHT ERROR] Division by Zero is undefined!
--- 2. AGE VERIFICATION DEMO ---
[EXCEPTION] Access Denied: User is under 18.
Program execution continued safely without crashing!
⚠️ Common Mistakes
- Throwing Plain Primitives Instead of
std::exceptionDerived Types: Writingthrow 404;orthrow "Error";makes exception handling inconsistent. Always derive or use classes from<stdexcept>(std::runtime_error,std::invalid_argument,std::out_of_range). - Throwing Exceptions Inside Destructors: If a destructor throws an exception while stack unwinding is already in progress, C++ immediately terminates the program (
std::terminate())! Mark destructorsnoexcept.
🛡️ Best Practices
- Catch exceptions by
constreference (catch (const std::exception& e)). - Use
noexceptkeyword on functions that are guaranteed never to throw exceptions (void safeFunc() noexcept).
🧪 Try It Yourself
- Write a function
checkArrayAccess(int index)that throwsstd::out_of_rangeif the requested index exceeds valid array boundaries. - Catch
std::bad_allocwhen attempting to allocate an unrealistically huge dynamic array.
🎯 Mini Challenge
Write a bank withdrawal function withdrawMoney(double balance, double amount) that throws std::runtime_error("Insufficient Balance") if amount exceeds balance and std::invalid_argument("Invalid Amount") if amount $\le 0$. Test it inside a try-catch block.
🔗 Related Topics
🧭 Navigation
| ← C++ Home | ← Previous: Lambdas | Next: File Streams → |