2015-08-20 7 views
6

मैं एक कंटेनर के लिए ड्रॉप-प्रतिस्थापन लिख रहा हूं, और मैं को सभी अपवाद-गारंटी प्राप्त करने की कोशिश कर रहा हूं। मैं वर्तमान में clear विधि लिख रहा हूं, और मैं इसे जितना संभव हो सके पूरा करना चाहता हूं, और हमेशा एक स्थिर स्थिति में कंटेनर छोड़ने के लिए, भले ही विनाशकों में से एक अपवाद फेंक दें। मैं सफाई करने के बाद अपवाद के बिना अपवाद को भी पुनर्स्थापित करना चाहता हूं, अधिमानतः बिना स्लाइसिंग के।एक अपवाद वस्तु कब नष्ट हो जाती है (और इसे नियंत्रित किया जा सकता है)?

यह मुझे प्रश्न पर लाता है; एक अपवाद कब नष्ट किया गया है? आइए एक प्रयास को देखें: यह उदाहरण के लिए सरलीकृत है।

void container::clear() 
{ 
    bool had_exception = false; 
    std::exception* exp; 
    internal_set_empty(); // this cant throw 
    while(! internal_done()) 
    { 
     try 
     { 
      internal_destruct_next(); // this might throw if T::~T() throws 
     } 
     catch(std::exception& e) 
     { 
      had_exception = true; 
      exp = &e; 
     } 
    } 
    if(had_exception) 
     throw *exp; 
} 

मैं इस, बुरी तरह विफल क्योंकि अपवाद शायद है विलुप्त जब यह संभाला माना जाता है की उम्मीद है, और इस तकनीकी रूप से rethrow नहीं करता है।

एक और प्रयास अपवाद की एक प्रतिलिपि लेगा, कुछ मुझे उम्मीद है कि टुकड़ा होगा।

क्या अपवाद के जीवनकाल को बढ़ाने का कोई तरीका है ताकि मैं बाद में को फिर से निकाल सकूं? यदि संभव हो, तो मैं catch(...) के माध्यम से पकड़े गए अपवादों को फिर से भरने में सक्षम होना चाहूंगा।

+0

http: // en।यदि आपका परिदृश्य काम कर सकता है तो cppreference.com/w/cpp/error/exception_ptr आसान हो सकता है। – Mat

+0

@Mat 'upgrade_ptr' ठीक वैसे ही लगता है जो मैं खोज रहा था, लेकिन ऐसा लगता है कि एक और मौलिक समस्या है। – sp2danny

उत्तर

4

भले ही विनाशकर्ता में से एक एक अपवाद

नहीं किया जा सकता है फेंक देते हैं। विनाशक एक कारण के लिए परेशान हैं- आप एक फेंकने वाले विनाशक से ठीक नहीं हो सकते हैं। यह स्पष्ट है कि आप उन वस्तुओं को साफ करने के लिए कुछ भी नहीं करते हैं जिनके विनाशक ने फेंक दिया- क्योंकि आप इसे करने की कोशिश भी कर सकते हैं- लेकिन इसका यह भी अर्थ है कि आपने उन्हें ज़ोंबी राज्य में लटका दिया है।

अपने अधिक विशिष्ट प्रश्न पर, आप प्रत्यावर्तन इस्तेमाल कर सकते हैं पकड़ के ढेर फ्रेम के अंदर रहने के लिए तत्वों को हटाने रखने की कोशिश करने के लिए, या आप भी सी ++ 11 जो चारों ओर अपवाद के परिवहन के लिए करना है में std::exception_ptr और दोस्तों के इस्तेमाल कर सकते हैं।

+0

धन्यवाद। मैंने यह भी पाया [http://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor) दिलचस्प होने के लिए – sp2danny

1

कॉलर के अपवाद को पारित करने के लिए वर्तमान उपयोग कैच ब्लॉक में इसे पुनर्स्थापित करना है। मान लें कि आपके पास ऐसा करने के अच्छे कारण नहीं हैं, std::exception_ptr का उपयोग करने का एकमात्र अन्य सही तरीका है। केवल std::exception* के साथ उच्च जोखिम है कि अपवाद नष्ट हो गया है और इसकी स्मृति को फिर से फेंकने से पहले इसे हटा दिया गया है।

स्टैंडर्ड सी ++ 2011 मसौदा (n4296) 15.1 पर कहते हैं एक अपवाद § 4 फेंकने: अपवाद वस्तु या तो अंतिम शेष सक्रिय अपवाद बाहर निकलता है के लिए किसी भी तरह से हैंडलर के बाद नष्ट हो जाता है अन्य rethrowing, या पिछले की तुलना में प्रकार std :: upgrade_ptr का ऑब्जेक्ट जो अपवाद ऑब्जेक्ट को संदर्भित करता है नष्ट हो गया, जो भी बाद में हो। पूर्व मामले में, विनाश तब होता है जब हैंडलर बाहर निकलता है, तुरंत हैंडलर में अपवाद-घोषणा में घोषित वस्तु के विनाश के बाद, यदि कोई हो। बाद में मामले में, विनाश std :: upgrade_ptr रिटर्न के विनाशक से पहले होता है। कार्यान्वयन तब अपवाद ऑब्जेक्ट के लिए स्मृति को हटा सकता है; इस तरह के किसी भी डीलोकेशन को अनिर्दिष्ट रास्ता (मेरा जोर दें)

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