try, catch, throw
C mein error handling manual hai (return codes check karte raho, jaise malloc() ka NULL check). C++ "exceptions" deta hai — ek structured tareeka errors ko signal karne aur handle karne ka, normal code flow se alag.
try block mein wo code likhte ho jo fail ho sakta hai. Agar exception throw hoti hai (throw keyword se), control seedha matching catch block mein jump karta hai — beech ka baaki code skip ho jaata hai. Agar koi exception nahi aati, catch block simply skip ho jaata hai.
#include <stdexcept>
using namespace std;
double divide(double a, double b) {
if (b == 0) {
throw runtime_error("Division by zero!"); // exception throw karo
}
return a / b;
}
int main() {
try {
cout << divide(10, 2) << endl; // 5 — normal
cout << divide(5, 0) << endl; // exception throw hoga
cout << "Ye line kabhi nahi chalegi" << endl;
} catch (const runtime_error &e) {
cout << "Error: " << e.what() << endl; // "Error: Division by zero!"
}
cout << "Program continue chal raha hai" << endl; // crash nahi hua
return 0;
}- throw = exception signal karo, try = risky code, catch = handle karo
- Exception aane par control seedha catch block mein jump karta hai
- Unhandled exception poora program crash kar deta hai
Ek try block ke saath multiple catch blocks ho sakte hain — alag-alag exception types ke liye alag handling. Order matter karta hai: specific types pehle, generic (jaise catch(...)) sabse aakhir mein.
try {
// risky code
throw runtime_error("something failed");
} catch (const invalid_argument &e) {
cout << "Invalid argument: " << e.what() << endl;
} catch (const runtime_error &e) {
cout << "Runtime error: " << e.what() << endl; // ye chalega
} catch (...) {
cout << "Kuch aur exception aayi" << endl; // catch-all, sabse last
}Jab exception throw hoti hai aur try block se bahar propagate hoti hai (catch tak pahunchne ke liye), beech mein aane wale saare local objects ke destructors automatically call hote hain ("stack unwinding") — RAII pattern isi guarantee par depend karta hai resource cleanup ke liye.
class Resource {
public:
~Resource() { cout << "Resource cleaned up!" << endl; }
};
void risky() {
Resource r; // local object
throw runtime_error("Oops");
// r ka destructor yahin nahi chalega (unreachable code hai)
}
int main() {
try {
risky();
} catch (...) {
cout << "Caught" << endl;
}
// Output: "Resource cleaned up!" (stack unwind hote waqt) phir "Caught"
return 0;
}