डिफ़ॉल्ट / कॉपी / चाल ctor और कॉपी / चाल असाइनमेंट ऑपरेटर की स्वचालित पीढ़ी के लिए शर्तें?


127

मैं अपनी मेमोरी को उन शर्तों पर रीफ्रेश करना चाहता हूं जिनके तहत एक कंपाइलर आमतौर पर ऑटो एक डिफॉल्ट कंस्ट्रक्टर, कॉपी कंस्ट्रक्टर और असाइनमेंट ऑपरेटर तैयार करता है।

मुझे याद है कि कुछ नियम थे, लेकिन मुझे याद नहीं है, और ऑनलाइन एक सम्मानित संसाधन भी नहीं मिल रहा है। क्या कोई मदद कर सकता है?

जवाबों:


136

निम्नलिखित में, "ऑटो-जनरेट" का अर्थ है "अंतर्निहित रूप से डिफ़ॉल्ट रूप से घोषित, लेकिन हटाए गए के रूप में परिभाषित नहीं"। ऐसी परिस्थितियां हैं जहां विशेष सदस्य फ़ंक्शन घोषित किए जाते हैं, लेकिन हटाए गए के रूप में परिभाषित किया गया है।

  • यदि कोई उपयोगकर्ता-घोषित कंस्ट्रक्टर (/12.1 / 5) नहीं है, तो डिफ़ॉल्ट रचनाकार स्वतः-जनरेट किया जाता है।
  • यदि उपयोगकर्ता-घोषित चाल निर्माणकर्ता या चाल असाइनमेंट ऑपरेटर नहीं है, तो प्रतिलिपि निर्माणकर्ता स्वतः-जनरेट किया जाता है (क्योंकि C ++ 03 में कोई मूव कन्स्ट्रक्टर या मूव असाइनमेंट ऑपरेटर नहीं हैं, यह C ++ 03 में "हमेशा" सरल होता है) ( §12.8 / 8)।
  • उपयोगकर्ता द्वारा घोषित चाल निर्माणकर्ता या चाल असाइनमेंट ऑपरेटर ()12.8 / 19) नहीं होने पर कॉपी असाइनमेंट ऑपरेटर स्वतः उत्पन्न होता है।
  • यदि उपयोगकर्ता द्वारा घोषित विध्वंसक (/12.4 / 4) नहीं है, तो विध्वंसक स्वतः उत्पन्न होता है।

C ++ 11 और बाद में केवल:

  • यदि उपयोगकर्ता द्वारा घोषित कॉपी कंस्ट्रक्टर, कॉपी असाइनमेंट ऑपरेटर या डिस्ट्रक्टर नहीं है, और यदि उत्पन्न मूव कंस्ट्रक्टर वैध है (.812.8 / 10) तो चाल निर्माणकर्ता स्वतः उत्पन्न होता है।
  • यदि उपयोगकर्ता द्वारा घोषित कॉपी कंस्ट्रक्टर, कॉपी असाइनमेंट ऑपरेटर या डिस्ट्रक्टर नहीं है, और यदि उत्पन्न चाल असाइनमेंट ऑपरेटर वैध है (जैसे अगर इसे निरंतर सदस्यों को असाइन करने की आवश्यकता नहीं होगी) (.812.8) 21)।

9
एक विरासत में मिली विध्वंसक गिनती होती है? मेरा मतलब है, मैं एक खाली वर्चुअल डिस्ट्रक्टर के साथ बेस क्लास मिला हूं। क्या यह उपवर्गों में चाल निर्माणकर्ताओं के निर्माण को रोकता है? यदि उत्तर हाँ है, तो क्या मैं आधार कक्षा में एक चाल निर्माणकर्ता को परिभाषित करने में मदद करूँगा?
kamilk

10
मुझे लगता है कि आपको शायद इस बात का उल्लेख करना चाहिए कि constकक्षा में सदस्य निर्माणकर्ता को ऑटो-जेनरेट होने से रोकेंगे ...
nonsensickle

क्या "ऐसी परिस्थितियां हैं जहां विशेष सदस्य फ़ंक्शन घोषित किए जाते हैं, लेकिन हटाए गए के रूप में परिभाषित किए जाते हैं।" उदाहरण के लिए, जहां आपके पास कास्ट या संदर्भ सदस्य हैं जहां स्थानांतरित करना असंभव होगा? नहीं, यह नहीं हो सकता है, क्योंकि वहाँ कॉपी लागू की जाएगी।
towi

मुझे पता है कि इस फोरम में हाइपरलिंक्स भेजना प्रतिबंधित है। लेकिन यह भी अच्छा लेख है - cplusplus.com/articles/y8hv0pDG
bruziuz

ध्यान दें, मानक के रूप में एक अंतर्निहित डिफ़ॉल्ट कॉपी कंस्ट्रक्टर " हटा दिया गया है यदि क्लास में उपयोगकर्ता द्वारा घोषित कॉपी असाइनमेंट ऑपरेटर या उपयोगकर्ता द्वारा घोषित विध्वंसक है " ( 12.8 कॉपी और चलती क्लास ऑब्जेक्ट [class.copy) )।
सिगी

98

मैं बहुत उपयोगी नीचे आरेख मिला है।

सी ++ स्वचालित निर्माता और असाइनमेंट ऑपरेटरों के लिए नियम से चिपचिपा बिट्स - शून्य हीरो की एक नियम बनना


सुंदर। "स्वतंत्र" किसको संदर्भित करता है? क्या से स्वतंत्र?
टावी

8
प्रतिलिपि ctor / असाइनमेंट एक दूसरे से 'स्वतंत्र' हैं। यदि आप सिर्फ एक लिखते हैं, तो संकलक दूसरे को प्रदान करेगा। इसके विपरीत, यदि आप या तो एक चाल ctor या एक चाल असाइनमेंट प्रदान करते हैं, तो संकलक दूसरे की आपूर्ति नहीं करेगा।
मार्को एम।

आश्चर्य है कि कॉपी संचालन के पीछे क्या कारण स्वतंत्र है। ऐतिहासिक कारण हो सकते हैं? या तथ्य यह है कि प्रतिलिपि इसे संशोधित नहीं करेगी लेकिन लक्ष्य क्या है?
RaGa__M

@Explorer_N हाँ, पिछड़ी संगतता, इसलिए ऐतिहासिक कारण। यह बहुत समय पहले एक खराब डिजाइन विकल्प था, इसलिए अब बग्स को खोजने के लिए "तीन का नियम" (सभी 3 या कोई भी परिभाषित करें: कॉपी कंस्ट्रक्टर, कॉपी असाइनमेंट ऑपरेटर, और अक्सर विध्वंसक) से बचने के लिए अच्छे अभ्यास की आवश्यकता है।
अटालाश

@MarcoM।, जहां तक ​​मैंने समझा है, "अगर आप लिखते हैं ..." शर्त में विशेष सदस्य फ़ंक्शन को सेट करने के दो मामले शामिल हैं = delete(स्पष्ट) या = default(मेरे लिए कम स्पष्ट)। क्या मैं सही हू?
एनरिको मारिया डे एंजेलिस

2

C ++ 17 N4659 मानक ड्राफ्ट

एक त्वरित क्रॉस मानक संदर्भ के लिए, निम्नलिखित अप्रतिष्ठित प्रविष्टियों के "निहित-घोषित" खंडों पर एक नज़र डालें:

वही जानकारी मानक से प्राप्त की जा सकती है। जैसे C ++ 17 N4659 मानक ड्राफ्ट :

15.8.1 "कॉपी / मूव कंस्ट्रक्टर्स" कॉपी कंस्ट्रक्टर के लिए कहते हैं:

6 यदि कक्षा की परिभाषा स्पष्ट रूप से कॉपी निर्माता की घोषणा नहीं करती है, तो एक गैर-स्पष्ट रूप से स्पष्ट रूप से घोषित किया जाता है। यदि वर्ग परिभाषा एक चाल निर्माणकर्ता या चाल असाइनमेंट ऑपरेटर की घोषणा करती है, तो अंतर्निहित घोषित प्रतिलिपि निर्माता को हटाए जाने के रूप में परिभाषित किया गया है; अन्यथा, इसे डिफ़ॉल्ट (11.4) के रूप में परिभाषित किया गया है। बाद का मामला तब हटा दिया जाता है जब वर्ग में उपयोगकर्ता द्वारा घोषित कॉपी असाइनमेंट ऑपरेटर या उपयोगकर्ता द्वारा घोषित विध्वंसक होता है।

और मूव कंस्ट्रक्टर के लिए:

8 यदि कक्षा X की परिभाषा स्पष्ट रूप से एक चाल निर्माणकर्ता की घोषणा नहीं करती है, तो एक गैर-स्पष्ट व्यक्ति को केवल और केवल यदि डिफ़ॉल्ट रूप से डिफ़ॉल्ट रूप से घोषित किया जाएगा

  • ((.१) - एक्स में उपयोगकर्ता द्वारा घोषित कॉपी कंस्ट्रक्टर नहीं है,

  • (8.2) - X के पास उपयोगकर्ता द्वारा घोषित कॉपी असाइनमेंट ऑपरेटर नहीं है,

  • (8.3) - X में उपयोगकर्ता द्वारा घोषित चाल असाइनमेंट ऑपरेटर नहीं है, और

  • ((.४) - X में उपयोगकर्ता-घोषित विध्वंसक नहीं है।

15.8.2 कॉपी असाइनमेंट के लिए "कॉपी / मूव असाइनमेंट ऑपरेटर" कहता है:

2 यदि वर्ग परिभाषा स्पष्ट रूप से कॉपी असाइनमेंट ऑपरेटर की घोषणा नहीं करती है, तो एक को स्पष्ट रूप से घोषित किया जाता है। यदि वर्ग परिभाषा एक चाल निर्माणकर्ता या चाल असाइनमेंट ऑपरेटर की घोषणा करती है, तो अंतर्निहित रूप से घोषित प्रतिलिपि असाइनमेंट ऑपरेटर को हटा दिया गया है; अन्यथा, इसे डिफ़ॉल्ट (11.4) के रूप में परिभाषित किया गया है। उत्तरार्द्ध मामले को हटा दिया जाता है यदि वर्ग में उपयोगकर्ता-घोषित प्रतिलिपि निर्माता या उपयोगकर्ता-घोषित विध्वंसक होता है।

और चाल असाइनमेंट के लिए:

4 यदि एक कक्षा X की परिभाषा स्पष्ट रूप से एक चाल असाइनमेंट ऑपरेटर की घोषणा नहीं करती है, तो किसी को केवल और केवल यदि डिफ़ॉल्ट रूप से डिफ़ॉल्ट रूप से घोषित किया जाएगा

  • (४.१) - एक्स के पास उपयोगकर्ता-घोषित कॉपी कंस्ट्रक्टर नहीं है,
  • (४.२) - X के पास उपयोगकर्ता-घोषित चाल निर्माणकर्ता नहीं है,
  • (4.3) - X में उपयोगकर्ता द्वारा घोषित कॉपी असाइनमेंट ऑपरेटर और नहीं है
  • (4.4) - X में उपयोगकर्ता-घोषित विध्वंसक नहीं है।

15.4 "विध्वंसक" इसे विध्वंसक के लिए कहते हैं:

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.