2017-12-27 11 views
8

निम्नलिखित कोड अच्छी तरह से संकलित किया गया है:का प्रयोग = के अर्थ में डिफ़ॉल्ट = हटाना

struct B { 
    B(int) {} 
}; 

struct D : B { 
    D() = default; 
}; 

जब तक मैं वर्ग D का एक उदाहरण बनाने के लिए:

D d; // error: use of deleted function 'D::D()' 

तो ऐसा कोई कारण (उपयोग के मामले है) D के कन्स्ट्रक्टर के लिए अनुमति देने के लिए, जब यह वास्तव में = delete; के रूप में काम करता है?

+0

यदि आप बी बदलते हैं, डी स्वचालित रूप से सही-सही काम करेगा। –

+0

आप किस कंपाइलर का उपयोग कर रहे हैं?ऐसा इसलिए हो सकता है क्योंकि आपकी संरचना खाली है और कुछ भी नहीं करता है, इसलिए संकलक इसे पूरी तरह से '= default' के साथ परिभाषित करता है? –

+1

जी ++ 5.1.0 'नोट: 'डी :: डी()' को पूरी तरह से हटा दिया गया है क्योंकि डिफ़ॉल्ट परिभाषा खराब हो जाएगी:' और 'त्रुटि: 'बी :: बी()'' –

उत्तर

11

g++ त्रुटि में एक अच्छा विवरण देता है:

bla.cpp:6:5: note: ‘D::D()’ is implicitly deleted because the default definition would be ill-formed: D() = default;

डिफ़ॉल्ट निर्माता D के सभी भागों का निर्माण करने का प्रयास करेंगे। आपके पास कोई फ़ील्ड नहीं है, लेकिन इसमें प्रारंभिक B है - जिसमें कोई खाली कन्स्ट्रक्टर नहीं है, केवल int एक है।

डिफ़ॉल्ट व्यवहार समझ में आता है - D जब तक कि यह स्पष्ट रूप से कहा जो int साथ B के निर्माण के लिए एक खाली निर्माता नहीं करना चाहिए था, और संकलक अनुमान लगाना नहीं चाहता है। अन्यथा आपके पास D ऑब्जेक्ट होगा, और B कन्स्ट्रक्टर B में जो होता है उसके आधार पर जंक हो सकता है, उदाहरण के लिए यदि कोई फ़ील्ड प्रारंभ करना है।

मुझे यकीन है कि अगर आप अपने सवाल का शाब्दिक मतलब जब आप से पूछना क्यों यह "अनुमति" है, के रूप में B डिफ़ॉल्ट निर्माता हटा दी जाती है नहीं कर रहा हूँ, लेकिन मैं दो कारणों के बारे में सोच सकते हैं:

  1. यह व्यवहार अच्छी तरह से परिभाषित किया गया है, और इसे अस्वीकार करने का कोई कारण नहीं है। त्रुटि का पता लगाना केवल तभी जब आप अवैध रूप से कुछ बनाने का प्रयास करते हैं, वैसे भी किया जाता है।
  2. यह अधिक लचीला है - B बदलने के लिए एक डिफ़ॉल्ट कन्स्ट्रक्टर स्वचालित रूप से D को एक होने की अनुमति देगा।
6

Is there any reason (use case) to allow = default for D's constructor, when it's actually works as = delete;?

यह =delete के रूप में काम नहीं करता। यह कहता है कि यह क्या कहना है। कि आप स्पष्ट रूप से संकलक उत्पन्न डिफ़ॉल्ट कार्यान्वयन चाहते हैं।

ऐसा इसलिए होता है कि संकलित किए गए संकलक को परिभाषित किया जाना चाहिए। क्योंकि B का डिफ़ॉल्ट कन्स्ट्रक्टर पूरी तरह से हटा दिया गया है।

+0

पर कॉल के लिए कोई मिलान करने वाला फ़ंक्शन नहीं मुझे पता है कि '= delete'' = default' नहीं है, लेकिन क्या मेरे पार्टिकलर मामले में एक भिन्नता है? मुझे पूरा यकीन है कि अगर मैं '= default' को' = delete' में बदलता हूं तो कुछ भी अर्थपूर्ण रूप से नहीं बदला जाता है। क्या मै गलत हु? – alexolut

+2

@alexolut - फ़ंक्शन किसी भी तरह से हटा दिया जाता है। कारण अलग है। यदि भविष्य में 'बी' को एक डिफ़ॉल्ट c'tor मिलता है, तो 'डी' भी होगा। यदि आप इसे हटाते हैं, तो यह नहीं होगा। कुछ लोग कहते हैं कि यह एक प्रमुख अर्थपूर्ण अंतर है। – StoryTeller

1

B में एक गैर-डिफ़ॉल्ट कन्स्ट्रक्टर है (इसका कन्स्ट्रक्टर एक तर्क लेता है जिसमें डिफ़ॉल्ट मान नहीं है)।

व्युत्पन्न D वर्ग इसलिए एक डिफ़ॉल्ट निर्माता नहीं है, उसके डिफ़ॉल्ट निर्माता को नष्ट कर दिया जाता है (जैसा कि संकलक D के लिए एक निर्माता है कि अपनी मूल वर्ग के B(int) निर्माता कॉल कर सकते हैं उत्पन्न नहीं कर सकते।)

D() = default; बस कहता है कि आप D के लिए डिफ़ॉल्ट कन्स्ट्रक्टर चाहते हैं, और ऊपर वर्णित अनुसार, डिफ़ॉल्ट कन्स्ट्रक्टर हटा दिया गया है।

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