2011-08-22 14 views
13

विनाशक को ट्रिगर करने के दायरे के सामान्य निकास के विपरीत फेंकने वाले अपवाद के कारण स्टैक की अनदेखी के दौरान इसे चलाने के लिए सी ++ में एक अच्छा तरीका क्या है? मैं जानना चाहता हूं कि मैं एक वर्ग बना सकता हूं जिसमें कुछ क्लीनअप कोड है जो हमेशा सामान्य निकास पर चलता है लेकिन अपवाद होने पर छोड़ दिया जाता है।पता लगाने के दौरान जब विनाशकारी चल रहा है?

+0

दिलचस्प सवाल! मुझे यह कहने का मोह है कि यह नहीं किया जा सकता है, क्योंकि वस्तुओं को वास्तव में पता नहीं है कि एक अपवाद सक्रिय है, वे सिर्फ दायरे से बाहर निकलते हैं क्योंकि अपवाद स्टैक को खोलता है, जैसे कि वे किसी अन्य से बाहर निकलते हैं गुंजाइश। यदि कुछ भी आपको कुछ प्लेटफार्म-विशिष्ट "हैक" की आवश्यकता होगी ... –

+1

उत्सुक क्यों आप स्टैक अनचाहे के दौरान सफाई से बचना चाहते हैं? –

+0

@ एरिक जेड: मैं इसे स्वचालित 'स्टैक' लॉगिंग के लिए उपयोग करने के बारे में सोचा था। 'लॉग xxx ("funcA -", arg1, arg2, arg3) की रेखाओं के साथ कुछ;;, लेकिन कार्यों का वाद्य यंत्र कठिन है। –

उत्तर

16

std::uncaught_exception() (<exception> में परिभाषित) अपने नाशक में आपको पता चलेगा कि यह एक अपवाद की वजह से बुलाया गया था:

class A 
{ 
public: 
    ~A() 
    { 
     if (std::uncaught_exception()) { 
      // Called because of an exception 
     } else { 
      // No exception 
     } 
    } 
}; 
+0

अच्छा, मैं कभी नहीं जानता था कि यह अस्तित्व में था! :-) –

+0

उतना अच्छा नहीं जितना आप सोच सकते हैं - मेरे पोस्ट पर लिंक किए गए लेख को देखें। – Simon

0

यहाँ एक तरह से मैं के बारे में सोच सकते हैं, लेकिन यह अनाड़ी लगता है:

{ 
    myCleanupClass unwindAction; 
    try { 
    // do some work which may throw exception. 
    } catch (...) { 
    unwindAction.disableDestructorWork(); 
    throw; 
    } 
} 
1

ऐसा तब तक न करें जब तक आपके पास कोई अच्छा कारण न हो। अवांछित ढेर ऐसी भाषा सुविधा है कि try ब्लॉक के अंदर सभी स्वचालित ऑब्जेक्ट्स को डिलीकेट करने के लिए लागू किया जाएगा, ताकि उनके अंदर संसाधनों को रिलीज़ करने का मौका मिले।

आप स्टैक को अनदेखा करते समय डीटीआर में क्लीनअप छोड़ना चाहते हैं, जो इसके मूल उद्देश्य को छोड़ देता है। और आप संसाधनों को लीक करने का जोखिम चलाएंगे।

उदाहरण

class CDBConnection 
{ 
    public: 
    CDBConnection() 
    { 
     m_db.open(); 
    } 
    ~CDBConnection() 
    { 
     if (!std::uncaught_exception()) 
     m_db.close(); 

     // if this is called during a stack unwinding, 
     // your DB connection will not be closed for sure. 
     // That's a resource leakage. 
    } 
    //.. 
    private: 
    DB m_db; 
}; 

void main() 
{ 
    //.. 
    try 
    { 
    // code that may throw 
    CDBConnection db; 
    //..   
    } 
    catch(const CDBException& exp) 
    { 
    // properly handle the exception 
    } 
} 
4

शायद this लेख आपको मदद मिलेगी। लेख आपको std :: uncaught_exception() के साथ समस्याएं दिखाएगा और इसमें सलाह दी गई है कि विनाशकों में अपवादों का सामना कैसे किया जाए।

संबंधित मुद्दे