2012-05-24 7 views
9

मान लीजिए मैं:सी ++ 11 में डिफॉल्ट वर्चुअल डिस्ट्रक्टर के लिए अपवाद विनिर्देश क्या है?

class Foo 
{ 
public: 
    virtual ~Foo()=default; 
}; 

डिफॉल्ट नाशक पर अपवाद-विनिर्देश क्या है?

virtual ~Foo() {}; 
or 
    virtual ~Foo() throw() {}; 
or 
    virtual ~Foo() noexcept {}; 

धारा सी ++ 11 मानक के 15.4 कहना है कि वह काम करता है सीधे नाशक का अंतर्निहित परिभाषा द्वारा लाया के अपवाद के विनिर्देशों पर निर्भर करता: डिफॉल्ट नाशक बराबर है। इस मामले में कोई सदस्य नहीं हैं, और कोई आधार वर्ग नहीं है, इसलिए AFAIK को निहित विनाशक द्वारा सीधे कोई कार्य नहीं किया जाता है। क्या यह मानक में एक अस्पष्टता (या चूक) है?

यह निश्चित रूप से महत्वपूर्ण है, क्योंकि अगर यह स्पष्ट रूप से फेंक दिया गया है, तो सभी उप-वर्गों को अपने विनाशकों को फेंक() के साथ घोषित करना होगा। मुझे मत बताओ विनाशकों में अपवाद फेंकना एक बुरा विचार है, मुझे पता है। मैं बहुत सारे विरासत कोड से निपटता हूं जहां अपवाद चश्मे का उपयोग नहीं किया जाता था।

जानकारी का एक बिंदु है, जब मैं करने की कोशिश की के रूप में:

class SubFoo : public Foo 
{ 
public: 
    virtual ~SubFoo(); 
}; 

मैं जीसीसी 4.4 में एक त्रुटि (बेमेल अपवाद चश्मा) मिल गया है (हालांकि मैं मानता हूं मुझे नहीं सही कमांड लाइन स्विच हो सकता था), लेकिन "11" कंपाइलर्स का उपयोग कर एक्सकोड 4.3 में नहीं।

उत्तर

4

वापस ऊपर पहले ही वाक्य (§15.4/14) में:

... इसके अंतर्निहित अपवाद-विनिर्देश प्रकार आईडी टी निर्दिष्ट करता है यदि और केवल यदि टी अपवाद द्वारा अनुमति दी है एक समारोह के सीधे च का अंतर्निहित परिभाषा द्वारा लाया के विनिर्देश, ... "

इसलिए, यदि ~Foo किसी भी कार्यों को लागू नहीं है, यह एक अंतर्निहित घोषणा कोई अपवाद नहीं फेंक दिया करने की अनुमति देता है कि है

अनुसार।§15.4/3 करने के लिए:

  • दोनों गैर फेंक (नीचे देखें), उनके रूप की परवाह किए बिना कर रहे हैं,

है कि:

दो अपवाद-विनिर्देशों संगत करता है, तो कर रहे हैं यहां मामला है, इसलिए यह वास्तव में कोई फर्क नहीं पड़ता कि घोषणा throw() या noexcept है - दोनों किसी भी मामले में संगत हैं।

+0

उत्तर के लिए धन्यवाद। कुछ और का पालन करने के लिए, spec का कहना है, "एक विनाशक की घोषणा जिसमें अपवाद-विनिर्देश नहीं है, को पूरी तरह से एक अपवाद घोषित करने के रूप में एक ही अपवाद-विनिर्देश माना जाता है" तो फिर "वर्चुअल ~ सबफू();" (अपवाद के बिना) बीमार नहीं है, जब तक कि यह सीधे उन कार्यों को आमंत्रित न करे जो स्पष्ट रूप से या स्पष्ट रूप से फेंकने की अनुमति देते हैं? – user1414050

+0

@ user1414050: मेरा मानना ​​है कि यह सही है, हाँ - लेकिन हम ' इस भाषा के छायादार पर्याप्त कोनों में शामिल हो रहे हैं कि मैं अभी तक इसे प्राप्त करने वाले अधिकांश कंपाइलरों पर बहुत अधिक शर्त नहीं लगाऊंगा। विशेष रूप से, मुझे संदेह है कि कई (अधिकांश?) कंपाइलर्स 'वर्चुअल ~ सबफू();' अर्थ के रूप में 'फेंक सकते हैं कुछ भी ", जैसा कि यह एक सामान्य कार्य के साथ होगा। –

+0

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

2

standardese में अच्छी तरह से सी ++ 11 §8.4.2/2 शुरू होता है,

एक समारोह स्पष्ट रूप से अपनी पहली घोषणा में चूक जाता है, तो
- यह परोक्ष अगर constexpr माना जाता है निहित घोषणा होगी,
- यह स्पष्ट रूप से एक ही अपवाद-विनिर्देश माना जाता है जैसे कि इसे स्पष्ट रूप से घोषित किया गया था (15.4), और नरकिप;

लेकिन फिर, सी ++ 11 §15 में।4/14, तर्क तेजी से devolves,

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

"अनुमति" के मानक अर्थ में यह एक अपवाद विनिर्देश के माध्यम से स्पष्ट रूप से अनुमति देने के बारे में है।

f दो कार्यों, जिनमें से एक को निर्दिष्ट कॉल करता है और इसलिए T की अनुमति देता है, और जिनमें से एक सभी अपवादों की अनुमति देता है, तो f दोनों Tऔर सभी अपवाद है, जो ’ टी संभव isn अनुमति देते हैं निर्दिष्ट करना होगा।

तो यह निश्चित रूप से मानक में एक दोष की तरह दिखता है।

मुझे एक संबंधित दोष रिपोर्ट, http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1351 मिली।

हालांकि, ऐसा लगता है कि यह क्षेत्र सिर्फ एक बड़ा संदेश है। :-(

+0

@ अनामित डाउनवॉटर देखें: कृपया अपना डाउनवोट समझाएं ताकि अन्य आपकी अंतर्दृष्टि से सीख सकें। –

+0

मुझे डीआर की तरह दिखता नहीं है; इसका मतलब यह है कि आपको 'अपवाद विनिर्देश' पर विचार करना होगा, 'सभी अपवादों को अनुमति देने' के उप-समूह के रूप में टी' निर्दिष्ट करता है। – MSalters

+0

@MSalters: इसके लिए कोई वाक्यविन्यास नहीं है? –

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