2011-09-28 19 views
14

मैं सी ++ 11 में एक छोटा सा प्रोग्राम लिख रहा हूं और वास्तव में पहली बार अपवादों का उपयोग करता हूं।अपवाद अच्छी प्रथाओं को पकड़ने के बारे में

मुझे अपवादों को कुशलतापूर्वक पकड़ने के तरीके के बारे में एक प्रश्न है, और कुछ googling के बाद भी मुझे जवाब नहीं है।

यहां प्रश्न है: (const?) Lvalue संदर्भ, या (const?) Rvalue संदर्भ द्वारा अपवाद को पकड़ने के बीच अधिक कुशल (या अनुशंसित) क्या है?

कोड में इस दे:

1)

try { throw std::exception{"what"}; } 
catch (std::exception& ex) {} 

2)

try { throw std::exception{"what"}; } 
catch (const std::exception& ex) {} 

3)

try { throw std::exception{"what"}; } 
catch (std::exception&& ex) {} 

4)

try { throw std::exception{"what"}; } 
catch (const std::exception&& ex) {} 
+1

रैवल्यू संदर्भ द्वारा पकड़ना भी अवैध है http://stackoverflow.com/q/21977340/5447906 –

उत्तर

31

का उपयोग आप स्थिरांक lvalue संदर्भ (2) द्वारा पकड़ने चाहिए:

try { throw std::exception{"what"}; } 
catch (const std::exception& ex) {} 

दलील:

सी ++ 11 में (shared_future के उपयोग के माध्यम से) यह संभव है कि दो धागे एक ही समय में एक ही अपवाद को अनदेखा कर सकते हैं। यह आपके कोड में तब भी हो सकता है जब तक कि आप shared_future का उपयोग नहीं कर रहे हैं, जब तक कि आप पूरे एप्लिकेशन को नियंत्रित न करें।

यदि दो थ्रेड एक ही अपवाद को अनदेखा कर पकड़े जाते हैं, और एक या दोनों धागे अपवाद को संशोधित करते हैं, तो आपको दौड़ की स्थिति मिल गई है।

इसलिए जब तक आपको कैच क्लॉज में अपवाद ऑब्जेक्ट को संशोधित करने की आवश्यकता नहीं है, तो संकलक को आपके लिए उस नीति को लागू करने दें - const& पर पकड़ें। यदि आपको वास्तव में अपवाद को संशोधित करने की आवश्यकता है, तो इसकी एक प्रति बनाएं, कॉपी संशोधित करें और प्रतिलिपि बनाएं। यदि आप सुनिश्चित हैं कि यह आपके अपवाद ऑब्जेक्ट को टुकड़ा नहीं करेगा (जो आमतौर पर मामला नहीं है तो आप std::exception को पकड़ रहे हैं) तो आप मूल्य से पकड़कर ऐसा कर सकते हैं।

+0

आपके उत्तर के लिए धन्यवाद, जो वास्तव में उपयोगी और स्पष्ट है। – Geoffroy

1

मुझे लगता है कि अपवाद सामान्य रूप से लैवल्यू-संदर्भ द्वारा पकड़ा जाना चाहिए। rvalues-संदर्भों के Here's अच्छा स्पष्टीकरण

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