30

में विधियों के लिए `= delete` का सही उपयोग क्या निम्न स्निपलेट सही है अन्य सभी जेनरेट किए गए तरीकों और कक्षाओं के लिए रचनाकारों को परिभाषित करने के लिए?कक्षाओं

struct Picture { 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no accidental construction, i.e. temporaries and the like 
    Picture() = delete; 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 

    // no move 
    Picture(Picture&&) = delete; 

    // no move-assign 
    Picture& operator=(Picture&&) = delete; // return type correct? 
}; 

यह प्रत्येक डिफ़ॉल्ट कंपाइलर कार्यान्वयन को हटा देता है और केवल विनाशक को छोड़ देता है, है ना? इसके बिना कक्षा (लगभग) अनुपयोगी मुझे लगता है, लेकिन मैं इसे भी हटा सकता हूं, सही?

क्या चाल-प्रकार Picture& चाल-असाइन operator=(Picture&&) सही है? अगर मैं वापसी प्रकार के लिए Picture&& लिखा तो क्या इससे कोई फर्क पड़ता है?

+3

ऐसा लगता है जैसे सी ++ वास्तव में सी ++ 0x में बहुत कुछ बदल गया है, दिलचस्प चीजें। – briantyler

+1

यह एक स्पष्ट वाक्यविन्यास है, फिर उन विधियों को 'निजी' अनुभाग में छिपाने का सामान्य अभ्यास, और केवल * घोषित * लेकिन * परिभाषित * नहीं। – towi

उत्तर

26

Xeo के जवाब के अलावा:

हाँ, सब कुछ सही है। क्या आप नष्ट कर दिया सदस्यों हटाए गए छोड़ कर प्रति निर्माता और नष्ट प्रति असाइनमेंट के सभी को समाप्त कर सकता है और एक ही प्रभाव है चाहता था, तो:

struct Picture { // Also ok 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 
}; 

प्रति निर्माता की स्पष्ट घोषणा डिफ़ॉल्ट निर्माता के अंतर्निहित पीढ़ी को रोकता है, इस कदम कन्स्ट्रक्टर और असाइनमेंट सदस्यों को ले जाएं। इन सदस्यों को स्पष्ट रूप से हटाकर स्वाद का विषय है। कुछ शायद इसे अच्छे दस्तावेज़ीकरण के रूप में देखेंगे। अन्य इसे अत्यधिक वर्बोज़ के रूप में देख सकते हैं।

+1

धन्यवाद, मैंने ड्राफ्ट टेक्स्ट में अनदेखा किया। यह टाइपिंग समय बचाता है। मुझे लगता है कि अगर मैं उन्हें चाहता हूं तो मैं उन्हें 'डिफ़ॉल्ट' कर सकता हूं? – towi

+1

हां। आप उन्हें स्पष्ट रूप से डिफ़ॉल्ट कर सकते हैं या स्पष्ट रूप से उन्हें हटा सकते हैं। –

3

मुझे ठीक लगता है। operator=का वापसी मान एक सामान्य संदर्भ होना चाहिए, भले ही ऑब्जेक्ट को रावल्यू संदर्भ से बनाया गया हो। ऐसा इसलिए है क्योंकि आप केवल एक lvalue (*this) को एक रैल्यू में संकलित नहीं कर सकते हैं।
और इसे उस गैर-कॉन्स Picture& operator=(Picture&&) प्रति रावल संदर्भ लेना चाहिए। आप निरंतर वस्तु से कैसे आगे बढ़ेंगे? ;)

+0

बेशक, मेरे बारे में मूर्खतापूर्ण कैसे। आप दोनों खातों पर सही हैं। मुझे इसे प्रश्न में सही करने दें, इसलिए पाठक मेरे दोषपूर्ण उदाहरण से नहीं सीखते हैं। – towi

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