C++ में उन्नत त्रुटि प्रबंधन: try/catch से औद्योगिक प्रथाओं तक
त्रुटि प्रबंधन औद्योगिक प्रोग्रामिंग की आधारशिलाओं में से एक है। C++ में, डेवलपर के पास न केवल क्लासिक try/catch तंत्र है, बल्कि उन्नत तकनीकों का एक पूरा शस्त्रागार भी है: RAII से लेकर अपवाद सुरक्षा गारंटी तक। इस लेख में, हम विश्लेषण करेंगे कि विश्वसनीय C++ कोड कैसे लिखें जो विफलताओं को सही ढंग से संभालता है, संसाधनों को लीक नहीं करता है, और पठनीय बना रहता है।
1. try/catch की मूल बातें और मानक जाल
मूल सिंटैक्स सभी से परिचित है:
#include <iostream>#include <stdexcept>
void dangerousFunction(int value) { if (value < 0) { throw std::invalid_argument("Value must be non-negative"); } // ... value के साथ काम}
int main() { try { dangerousFunction(-5); } catch (const std::invalid_argument& e) { std::cerr << "Error: " << e.what() << std::endl; } catch (const std::exception& e) { std::cerr << "Generic error: " << e.what() << std::endl; } catch (...) { std::cerr << "Unknown exception caught" << std::endl; } return 0;}महत्वपूर्ण बिंदु:
- संदर्भ द्वारा पकड़ें —
catch (const std::exception& e)ऑब्जेक्ट स्लाइसिंग से बचाता है। - catch-ब्लॉक का क्रम महत्वपूर्ण है: पहले अधिक विशिष्ट अपवाद, फिर सामान्य।
catch (...)का दुरुपयोग न करें — यह गंभीर त्रुटियों (जैसेstd::bad_alloc) सहित सभी त्रुटियों को छिपा देता है।- डिस्ट्रक्टर से कभी अपवाद न फेंकें — इससे अपरिभाषित व्यवहार होता है (आमतौर पर आपातकालीन समाप्ति)।
2. संसाधन प्रबंधन के लिए try/catch के विकल्प के रूप में RAII
RAII (Resource Acquisition Is Initialization) — C++ का एक प्रमुख पैटर्न है जो अपवादों को सुरक्षित बनाता है। विचार: संसाधन कंस्ट्रक्टर में प्राप्त किया जाता है और डिस्ट्रक्टर में मुक्त किया जाता है। यदि कोई अपवाद होता है, तो सभी बनाए गए ऑब्जेक्ट के डिस्ट्रक्टर स्वचालित रूप से कॉल होते हैं (stack unwinding)।
#include <fstream>#include <vector>#include <stdexcept>
void processFile(const std::string& filename) { std::ifstream file(filename); // RAII: फ़ाइल कंस्ट्रक्टर में खुलेगी if (!file.is_open()) { throw std::runtime_error("Cannot open file: " + filename); }
std::vector<int> data; int value; while (file >> value) { data.push_back(value); } // file का डिस्ट्रक्टर फ़ाइल को स्वचालित रूप से बंद कर देगा, // भले ही कोई अपवाद हो (जैसे push_back पर bad_alloc)}मैन्युअल try/catch पर RAII के लाभ:
finallyब्लॉक लिखने की आवश्यकता नहीं — डिस्ट्रक्टर सफाई की गारंटी देते हैं।- कोड अधिक रैखिक और पठनीय हो जाता है।
- अपवाद मेमोरी, फ़ाइल डिस्क्रिप्टर आदि के लीक का कारण नहीं बनते।
3. अपवाद सुरक्षा गारंटी
C++ में, फ़ंक्शन के लिए तीन स्तरों की गारंटी को अलग करने की प्रथा है:
- No-throw guarantee — फ़ंक्शन कभी अपवाद नहीं फेंकता।
noexceptसे चिह्नित किया जाता है। - Strong guarantee — यदि कोई अपवाद हुआ, तो प्रोग्राम की स्थिति अपरिवर्तित रहती है (परमाणु संक्रिया)।
- Basic guarantee — अपवाद पर संसाधन लीक नहीं होते, ऑब्जेक्ट सुसंगत स्थिति में रहते हैं, लेकिन उनका मान बदल सकता है।
Strong guarantee के साथ उदाहरण (copy-and-swap मुहावरा):
#include <algorithm> // std::swap के लिए#include <vector>#include <stdexcept>
class SafeVector { std::vector<int> data_;public: void push_back(int value) { // 1. बनाया जा रहा है