2012-05-25 14 views
6
namespace QuantLib { 

    //! Base error class 
    class Error : public std::exception { 
     public: 
     /*! The explicit use of this constructor is not advised. 
      Use the QL_FAIL macro instead. 
     */ 
     Error(const std::string& file, 
       long line, 
       const std::string& functionName, 
       const std::string& message = ""); 
     /*! the automatically generated destructor would 
      not have the throw specifier. 
     */ 
     ~Error() throw() {} 
     //! returns the error message. 
     const char* what() const throw(); 
     private: 
     boost::shared_ptr<std::string> message_; 
    }; 

} 

जैसा कि आप टिप्पणी के माध्यम से देखते हैं, वर्ग Error का विनाश स्पष्ट रूप से नो-थ्रो विनिर्देशक के साथ एक खाली कार्यान्वयन प्रदान करता है।क्या हमें नो-थ्रो विनिर्देशक के साथ विनाशक प्रदान करना चाहिए?

प्रश्न: क्या यह आवश्यक है? या क्या यह एक अच्छा अभ्यास है जो संकलक को एक निहित विनाशक उत्पन्न करने की तुलना करता है?

+0

मुझे अपने अपवाद वर्ग में कोई नो-थ्रो विनाशक जोड़ना पड़ा जो कि एक चेतावनी या त्रुटि को समाप्त करने के लिए std :: अपवाद से प्राप्त हुआ था, जब मैंने एक प्रदान नहीं किया था। यह पसंद नहीं आया कि व्युत्पन्न वर्ग में बेस क्लास के समान वें-थ्रो स्पेक नहीं था। –

+1

* यदि * आप ऐसा करने का निर्णय लेते हैं, तो यदि संभव हो तो मैं 'throw()' के बजाय 'noexcept' का उपयोग करूंगा। डायनामिक अपवाद विनिर्देश (जिसमें 'फेंक()', कम से कम मैंने इसे पढ़ा है) को बहिष्कृत किया गया है (हालांकि यदि आपका कंपाइलर स्नफ करने के लिए नहीं है, तो आप ऐसा करने में सक्षम नहीं हो सकते हैं)। –

उत्तर

8

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

यदि आप सी ++ 03 में हैं, तो आप इसे जोड़ना चाहेंगे, लेकिन क्या इसका असर होगा या नहीं, बहुत कार्यान्वयन परिभाषित किया गया है ... अब, दस्तावेज़ीकरण उद्देश्यों के लिए आप इसे जोड़ना चाहते हैं, लेकिन फिर से , आमतौर पर यह माना जाता है कि विनाशक फेंक नहीं देते हैं।

+0

मेरा मानना ​​है कि सी ++ 11 के बारे में सटीक नहीं है। – bames53

+0

सी ++ 11 में, एक डॉटर के पास एक अपवाद विनिर्देश है जो मूल रूप से किसी भी चीज से सीधे किसी भी चीज़ द्वारा फेंक दिया जाता है। यह केवल तभी है जब यह फेंकता हुआ कुछ भी नहीं कहता है। [कम से कम मुझे विश्वास है कि यह इरादा है - शब्द थोड़ा गन्दा है, इसलिए यह कम से कम तर्कसंगत आत्म-विरोधाभासी है]। –

+3

कुछ हफ्ते पहले मैं एक सहकर्मी के साथ मानक के इस हिस्से में गया था, और समस्या यह है कि अपवाद विनिर्देश (यदि विनाशक के लिए कोई भी नहीं दिया गया है) एक निश्चित रूप से घोषित विनाशक का होगा, जो बदले में संघ है उन सभी कार्यों के अपवाद विनिर्देशों के बारे में जो उस विनाशक की * अंतर्निहित परिभाषा * कॉल करेंगे, जो सभी सदस्यों और अड्डों के विनाशक हैं। उस समय हमारी समझ यह है कि '~ त्रुटि() {फेंक 1; च(); } ''f' फेंकने पर भी' अस्वीकरण '(अपवाद) अपवाद विनिर्देश होगा ... –

4

आपको लगता है कि throw() का मतलब है।

मानक के अनुसार इसका वास्तव में क्या अर्थ है, "यदि आवश्यक हो तो इस समारोह में प्रत्येक कॉल के आसपास अतिरिक्त कोड डालें, या यह सुनिश्चित करने के लिए कि यह फ़ंक्शन फेंकता है तो अपवाद पकड़ा जाता है और std::unexpected को" ।

कुछ कंप्यूटर्स ने इसका अर्थ यह स्वीकार करने के लिए किया है कि "इस समारोह में कॉल को ऑप्टिमाइज़ करें कि वे फेंक नहीं पाएंगे", लेकिन (मानक के उल्लंघन में) रनटाइम चेक को लागू नहीं किया था।

तो, इसे एक विनाशक (जिसे निश्चित रूप से फेंकना नहीं चाहिए) में जोड़ना (लेकिन अभ्यास में नहीं) एक रनटाइम चेक जोड़ना चाहिए जिसे कभी ट्रिगर नहीं किया जाना चाहिए और इसलिए आपके कोड को डीबग करने में मदद मिल सकती है। यह अनुकूलन को सक्षम या सक्षम नहीं कर सकता है।

3

Destructors हमेशा परोक्ष अपवाद विनिर्देशों है:

[class.dtor] 12.4 p3

कि एक अपवाद-विनिर्देश परोक्ष एक ही अपवाद माना जाता है नहीं है एक नाशक का एक घोषणा एक निहित घोषणा के रूप में विनिर्देश (15.4)।

[except.spec] 15.4 p14

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

तो, नहीं, अपवाद विनिर्देश का उपयोग करने के लिए यह आवश्यक नहीं है।


सी ++ उपयोगकर्ता 03 परिभाषित विनाशकर्ता में एक अंतर्निहित अपवाद विनिर्देश नहीं था, इसलिए यदि आप अपने खुद के नाशक को परिभाषित करते हैं आप संकलक पर भरोसा नहीं कर सकते स्वचालित रूप से उचित अपवाद विनिर्देश जोड़ने के लिए। लेकिन निस्संदेह घोषित किया गया है कि विनाशकों के पास सी ++ 11 में समान अंतर्निहित अपवाद विनिर्देश है।

+0

@ स्टेवेजसेप: पहला उद्धरण (§12.4/3) सी ++ 11 में नया है। सी ++ 03 में, दूसरा उद्धरण §15.4/13 क्रमांकित है, लेकिन (मुझे विश्वास है) एक ही शब्द है। –