2015-01-04 15 views
20

मैं एक स्वत: चर के रूप में इसका उपयोग करने से मेरी कक्षा का उपयोगकर्ता को रोकने के लिए चाहते हैं, इसलिए मैं इस तरह कोड लिखने:"= डिफ़ॉल्ट" विनाशक और खाली विनाशक के बीच क्या अंतर है?

class A { 
private: 
    ~A() = default; 
}; 

int main() { 
    A a; 
} 

मैं उम्मीद करते हैं कि कोड संकलित नहीं किया जाएगा, लेकिन जी ++ त्रुटि के बिना यह संकलित ।

हालांकि, जब मैं करने के लिए कोड बदलने के लिए:

class A { 
private: 
    ~A(){} 
}; 

int main() { 
    A a; 
} 

अब, जी ++ त्रुटि है कि ~A(), निजी है के रूप में मेरी उम्मीद है देता है।

"डिफ़ॉल्ट" विनाशक और खाली विनाशक के बीच क्या अंतर है?

+4

जीसीसी का कौन सा संस्करण? –

+1

पढ़ना उदा। [यह विनाशक संदर्भ] (http://en.cppreference.com/w/cpp/language/destructor), अंतर यह है कि उपयोगकर्ता द्वारा प्रदत्त विनाशक (भले ही यह खाली हो) * गैर-तुच्छ * है, और से संदर्भ: "छोटे विनाशकों के साथ ऑब्जेक्ट्स को डिलीट-एक्सप्रेशन की आवश्यकता नहीं होती है और इन्हें बस अपने स्टोरेज को डिलीकेट करके निपटान किया जा सकता है।" –

+8

आपके मामले में कोई अंतर नहीं है, दोनों [gcc4.9 और clang3.5 संकलन करने से इनकार करते हैं] (http://coliru.stacked-crooked.com/a/41976bc03bc12c79) आपका पहला उदाहरण। यह जीसीसी के आपके संस्करण में एक बग होना चाहिए। – Praetorian

उत्तर

23

आपका पहला उदाहरण संकलित नहीं होना चाहिए। यह संकलक में एक बग का प्रतिनिधित्व करता है जो यह संकलित करता है। यह बग जीसीसी 4.9 और बाद में तय है।

= default के साथ परिभाषित विनाशक इस मामले में त्रिभुज है। यह std::is_trivially_destructible<A>::value के साथ पता लगाया जा सकता है।

अद्यतन

सी ++ 11 (और सी ++ 14) कथन है कि यदि एक एक उपयोगकर्ता के घोषित नाशक है (और आप या तो नहीं है, तो उपयोगकर्ता के घोषित विशेष सदस्य के लिए कदम) , तो कॉपी कन्स्ट्रक्टर और कॉपी असाइनमेंट ऑपरेटर की अंतर्निहित पीढ़ी अभी भी होती है, लेकिन वह व्यवहार बहिष्कृत है। मतलब यदि आप इस पर भरोसा करते हैं, तो आपका कंपाइलर आपको एक बहिष्करण चेतावनी (या शायद नहीं) दे सकता है।

दोनों:

~A() = default; 

और:

~A() {}; 

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

यदि आप चालकों को घोषित करते हैं (विनाशक घोषित किए बिना या तो), तो कॉपी सदस्यों को पूरी तरह से हटा दिया जाता है।

+2

@ डेल्फीफर्स्ट: इन दिनों कंपाइलर कीड़े बहुत आम हैं। जब मैं एक छात्र था, 1 9 80 के दशक की शुरुआत में, हमने सीखा कि निश्चित रूप से किसी भी अप्रिय व्यवहार हमारे कोड में एक बग था, संकलक में नहीं। आज मैं नियमित रूप से कंपाइलर्स क्रैश (आईसीई, आंतरिक कंपाइलर त्रुटि) बना देता हूं, और फिर इसके बारे में कोई सवाल नहीं है कि इसकी गलती क्या है ... –

+0

@ हावर्ड हिन्नेंट: मुझे डिफॉल्ट बनाम कुछ घोषित घोषित नहीं किया गया है। मुझे लगता है कि "उपयोगकर्ता घोषित" वाक्यांश के मानक के उपयोग से संबंधित होगा, उदाहरण के लिए सी ++ 11 §12.8/18 में। कृप्या? –

+0

@ चीयर्संधथ.-अल्फ: मदद करने में खुशी हुई, लेकिन मुझे आपका प्रश्न समझ में नहीं आया। यदि आप पूछ रहे हैं कि कोई '= डिफ़ॉल्ट' विशेष सदस्य उपयोगकर्ता द्वारा घोषित किया गया है, तो उत्तर हाँ है, लेकिन उपयोगकर्ता द्वारा प्रदान नहीं किया गया है। –

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