2015-07-08 10 views
6

मैंने सिद्धांत में सोचा कि इस सवाल का जवाब हाँ था।आधार वर्ग में कॉपी कन्स्ट्रक्टर/ऑपरेटर निजी घोषित करके व्युत्पन्न कक्षा को अनावश्यक बनाया जा सकता है?

हालांकि, व्यावहारिक रूप से, मेरा कंपाइलर (वीएस -2010) निम्न स्थितियों में शिकायत नहीं कर रहा है: मेरे पास एक सामान्य बेस क्लास है जो कुछ सामान्य इंटरफ़ेस प्रदान करता है (अभी तक कोई डेटा सदस्य नहीं है) और इससे प्राप्त विभिन्न उप और सबबक्क्लास।

class Base 
{ 
public: 
    Base() {} 
    virtual ~Base() {} 

    virtual void interfaceFunction1() = 0; 
    virtual void interfaceFunction2() = 0; 
private: 
    Base(const Base&);   // all derived classes should be uncopyable 
    Base& operator=(const Base&); 

    // no data members 
}; 

मेरे कंपाइलर को उप-उप-वर्गों में पूर्ण प्रति रचनाकारों को भी लागू करने के लिए यह असंभव पाया गया।

मैं कैसे सुनिश्चित कर सकता हूं कि बेस से प्राप्त हर वर्ग अनिश्चित है?

संपादित करें: अगर मैं अच्छी तरह से समझ, यह वास्तव में क्या स्कॉट Meyers वर्ग Uncopyable (केवल एक पूर्ण इंटरफ़ेस वर्ग के लिए यहाँ विस्तारित) के बारे में उनकी विचार के साथ प्रभावी सी ++ (3 संस्करण, 2005) की मद 6 में विस्तार से बताया है। क्या अंतर है जो उसके विचार को काम करता है? (मुझे पता है कि उसे निजी रूप से विरासत मिलती है, लेकिन इससे कोई समस्या नहीं होनी चाहिए)

+0

एक डमी डेटा सदस्य जोड़ सकते हैं। –

+1

क्या आपने अन्य कंप्यूटर्स का परीक्षण किया था? एक व्युत्पन्न वर्ग भी प्रस्तुत करना अच्छा होगा;) (वास्तव में एक संगत उदाहरण की तरह कुछ अधिक।) – luk32

+0

शुद्ध फ़ंक्शन का उपयोग वर्चुअल चिह्नित नहीं है? –

उत्तर

3

यह संकलक को व्युत्पन्न कक्षाओं के लिए एक प्रतिलिपि बनाने वाले को उत्पन्न करने से रोकना चाहिए जो स्पष्ट रूप से घोषित नहीं करता है। हालांकि, कोई भी व्युत्पन्न वर्ग स्पष्ट रूप से प्रतिलिपि बनाने वाले को घोषित करने से रोकता है जो Base की कॉपी कन्स्ट्रक्टर को कॉल करने के अलावा कुछ और करेगा।

यह सुनिश्चित करने का कोई तरीका नहीं है कि व्युत्पन्न कक्षाएं तत्काल हैं लेकिन कॉपी करने योग्य नहीं हैं।

+0

क्या यह बेस() निजी बनाने का समाधान हो सकता है? (लेकिन फिर मुझे स्थिर फैक्ट्री विधियों का सहारा लेना होगा, जो इन वर्गों को अवांछित बनाने के लिए बहुत परेशानी की तरह लगता है) –

+0

@TG_ नहीं, यह काम नहीं करेगा। यदि आप * सभी * 'बेस 'कन्स्ट्रक्टर' निजी' छोड़ते हैं, तो व्युत्पन्न कक्षा स्वयं को प्रारंभ करने में सक्षम नहीं होगी (प्रतिलिपि द्वारा नहीं, डिफ़ॉल्ट रूप से नहीं, किसी भी अन्य तरीके से नहीं)।यदि आप किसी भी 'बेस' कन्स्ट्रक्टर को सुलभ छोड़ देते हैं, तो व्युत्पन्न कक्षा इसका उपयोग अपनी प्रतिलिपि ctor में कर सकती है। – Angew

1

कॉपी कन्स्ट्रक्टर/ऑपरेटर को निजी के रूप में घोषित करने की बजाय उन्हें हटाए जाने की घोषणा करने के बजाय। कॉपी कन्स्ट्रक्टर/ऑपरेटर को निजी रूप से घोषित करना व्युत्पन्न कक्षाओं को गैर-प्रतिलिपि बनाने का सबसे अच्छा समाधान नहीं है। यदि आप बेस क्लास को पूरी तरह से गैर-प्रतिलिपि बनाना चाहते हैं तो प्रतिलिपि निर्माता/ऑपरेटर को डी के रूप में घोषित करें क्योंकि प्रतिलिपि बेस के सदस्य कार्यों के अंदर अभी भी हो सकती है क्योंकि निजी सदस्य उस वर्ग के कार्यों तक पहुंच योग्य हैं। है भी सही जब तक आप अवगत हैं के रूप में निजी

Base(const Base&) = delete; // copy constructor 
Base& operator=(const Base&) = delete; // copy-assignment operator 

लेकिन घोषित प्रतिलिपि निर्माता/ऑपरेटर कि प्रति अब भी के सदस्य कार्यों के अंदर जगह ले जा सकते हैं: आप हटाने की सी ++ 11 सुविधा का उपयोग कर सकते हैं बेस

+1

उन्हें निजी बनाते हुए और हटाए जाने के रूप में घोषित करने के समान प्रभाव –

+0

@ BЈовић आवश्यक नहीं है, उन्हें निजी बनाने से यह सुनिश्चित नहीं होता है कि उस प्रकार की वस्तुएं कॉपी करने योग्य नहीं हैं। अगर हम उन्हें हटाए जाने की घोषणा करते हैं तो कोई प्रतिलिपि कभी नहीं हो सकती है। प्रभावी आधुनिक सी ++ के आइटम 11 में कहा गया है कि कोड और सदस्य फ़ंक्शन में कोड संकलित करने में विफल हो जाएगा यदि यह हटाए गए सदस्य फ़ंक्शन का उपयोग करने का प्रयास करता है। उन्हें निजी अर्थ के रूप में घोषित करना कि उस विशेष वर्ग के सदस्य कार्यों और दोस्तों के अंदर कोड उनका उपयोग कर सकता है और लापता कार्य परिभाषा के कारण लिंकिंग विफल हो जाएगी। –

+1

एक डिफ़ॉल्ट प्रति-निर्माता नई बेस ऑब्जेक्ट बनाएगा, और इसे कॉपी करने का प्रयास नहीं करेगा। इसलिए, यह दृष्टिकोण काम नहीं करेगा, अगर व्युत्पन्न कक्षा डिफ़ॉल्ट प्रतिलिपि कन्स्ट्रक्टर का उपयोग करती है, और व्युत्पन्न वर्ग कॉपी करने योग्य होगा, जबकि आधार नहीं है। –

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

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