2014-10-01 6 views
14

मैं यहाँ प्रतिलिपि कंस्ट्रक्टर्स पर cppreference पेज की समीक्षा कर रहा हूँ: http://en.cppreference.com/w/cpp/language/copy_constructorनिहित रूप से घोषित और निहित रूप से परिभाषित प्रति रचनाकारों के बीच भेद क्या है?

मैं परोक्ष-घोषित प्रतिलिपि निर्माणकर्ता और परोक्ष से परिभाषित प्रति कंस्ट्रक्टर्स के बारे में 2 वर्गों काफी कुछ समय पढ़ा है लेकिन मैं अभी भी समझ में नहीं आता भेद। एक निश्चित रूप से घोषित नहीं किया जाएगा लेकिन परिभाषित कन्स्ट्रक्टर परिणाम लिंकर समस्याओं में नहीं होगा?

नियम बहुत जटिल हैं। मुझे याद नहीं है कि सी ++ 03 में एक भेद है: या तो आपके पास एक कंपाइलर जेनरेट कॉपी कन्स्ट्रक्टर था या आपने नहीं किया था।

क्या कोई इन शब्दों को (सरल शब्दों में) समझा सकता है कि इन दो श्रेणियों के बीच अंतर/मतभेद क्या हैं?

उत्तर

11

इस खंड 12 की शुरुआत में मानक में एक नोट में स्पष्ट किया जाता है:

[नोट: कार्यान्वयन परोक्ष कुछ वर्ग प्रकार के लिए इन सदस्य कार्यों घोषणा करेंगे जब कार्यक्रम नहीं है स्पष्ट रूप से उन्हें घोषित करें। अगर वे ओडीआर-प्रयुक्त (3.2) हैं तो कार्यान्वयन उन्हें निश्चित रूप से परिभाषित करेगा। 12.1, 12.4 और 12.8 देखें। - अंत टिप्पणी]

के लिए सी ++ 14 मानक संदर्भ (N3936) कर रहे हैं 12.1/5, 12.4/6, 12.8/13, 12.8/26।प्रत्येक मामले में संबंधित विशेष सदस्य फ़ंक्शन को निश्चित रूप से परिभाषित किया जाता है यदि इसे डिफॉल्ट किया गया है और हटाए गए रूप में परिभाषित नहीं किया गया है, या तो ओडीआर-प्रयुक्त या स्पष्ट रूप से डिफॉल्ट किया गया है। अगर हम जैसे

struct Foo {}; 

कुछ और प्रकार Foo का कोई वस्तुओं कभी बनाई गई हैं, सभी छह विशेष सदस्य कार्यों (, डिफ़ॉल्ट निर्माता, नाशक निर्माता कॉपी, ले जाने के निर्माता, असाइनमेंट ऑपरेटर कॉपी, ले जाने के असाइनमेंट ऑपरेटर) परोक्ष घोषणा की जाती है डिफ़ॉल्ट रूप से, लेकिन परिभाषित नहीं किया गया है क्योंकि वे odr-used नहीं हैं।

+1

बहुत बढ़िया स्पष्टीकरण। मुझे विभिन्न परिदृश्यों के अधिक उदाहरण देखना पसंद आएगा जो अन्य हटाए गए/अंतर्निहित परिभाषित/तुच्छ स्थितियों के साथ निहित घोषणा को जोड़ते हैं। –

3

यदि कोई निहित रूप से घोषित प्रतिलिपि निर्माता है, तो इसे हमेशा परिभाषित किया जाता है। इसकी परिभाषा के लिए विकल्प हैं:

  • नष्ट कर दिया
  • तुच्छ
  • परोक्ष परिभाषित

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

आपके द्वारा लिंक किया गया पृष्ठ वर्णन करता है कि उपर्युक्त तीनों में से प्रत्येक विकल्प किस स्थिति में होता है।

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

के बीच अंतर छोटे पैमाने पर प्रतिलिपि और त्रिकोणीय रूप से प्रतिलिपि बनाने योग्य नहीं था लेकिन यह काफी स्पष्ट रूप से नहीं बताया गया था; आपने पीओडी के नियमों से अनुमान लगाया है जिसमें वस्तुओं की प्रतिलिपि बनाने के लिए memcpy का उपयोग करने की अनुमति दी गई थी।

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

+0

शायद मुझे गलत जानकारी दी गई है लेकिन घोषणाएं परिभाषाओं का एक उप-समूह हैं। दूसरे शब्दों में, अगर कुछ परिभाषित किया गया है तो यह भी घोषित किया जाता है। हालांकि, अगर कुछ घोषित किया गया है तो इसका मतलब यह नहीं है कि यह परिभाषित किया गया है (इस प्रकार हमने कहा होगा कि इसे परिभाषित किया गया था) –

+1

@ void.pointer आप उपयोगकर्ता द्वारा प्रदत्त वाक्यविन्यास संरचनाओं के बारे में बात कर रहे हैं। यह कंपाइलर द्वारा उत्पन्न रचनाकारों के बारे में बात कर रहा है। कंपाइलर कभी भी इसे परिभाषित किए बिना एक फ़ंक्शन घोषित करता है (ठीक है - जैसा कि ब्रायन बताता है, संकलक परिभाषा उत्पन्न करने के लिए परेशान नहीं होगा अगर इसे वास्तव में कभी नहीं कहा जाता है)। –

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

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