2013-05-26 10 views
14

उदाहरण के लिए, मैं एक वर्ग घोषित करने के लिए चाहते हैं, लेकिन मैं चाहता हूँ ग्राहक नहीं करने के लिए प्रतिलिपि निर्माता का उपयोग कर सकेंगे (या असाइनमेंट ऑपरेटर कॉपी)एक कन्स्ट्रक्टर निजी और = हटाने के बीच अंतर क्या है?

निम्न दो के दोनों प्रतिलिपि निर्माता के उपयोग की अनुमति नहीं है:

1.

class Track 
{ 
public: 
    Track(){}; 
    ~Track(){}; 
private: 
    Track(const Track&){}; 
}; 

2.

class Track 
{ 
public: 
    Track(){}; 
    ~Track(){}; 
    Track(const Track&)=delete; 
}; 

क्या इनमें से एक तरीका दूसरे की तुलना में "अधिक सही" है या बराबर है? क्या कोई दुष्प्रभाव है?

//Does not compile with both the above ways 
int main() 
{ 
    Track l; 
    Track p(l); 
} 
+0

क्या यह संकलित 'ट्रैक (कॉन्स ट्रैक और) = हटाएं; '??? –

+1

@EdHeal हाँ, यह करता है। जी ++ 4.7 –

+0

पहले 'हटाएं' के इस तरह के उपयोग को नहीं देखा। भाषा विस्तार? यदि हां, पहले की तुलना में निश्चित रूप से "अधिक सही" – kotlomoy

उत्तर

15

इसे निजी बनाना इसे करने का "पुराना" तरीका है। कन्स्ट्रक्टर अभी भी मौजूद है, लेकिन यह निजी है, और इसे केवल दूसरे वर्ग के सदस्य समारोह के भीतर से ही बुलाया जा सकता है।

= delete निर्माता को हटा देता है। यह संकलक द्वारा उत्पन्न नहीं होता है, और यह बस अस्तित्व में नहीं होगा।

तो सबसे अधिक संभावना है, = delete वह है जो आप चाहते हैं। (हालांकि चेतावनी के साथ कि सभी कंपाइलर्स अभी तक इस वाक्यविन्यास का समर्थन नहीं करते हैं, इसलिए यदि पोर्टेबिलिटी चिंता का विषय है ...)

6

, एक प्रति निर्माता private अभी भी Track वर्ग के सदस्य कार्यों उस वर्ग के उदाहरणों कॉपी-निर्माण करने के लिए अनुमति देता है की घोषणा करते हुए कर रही यह बस नष्ट कर दिया है कि वस्तु कॉपी-निर्माण की मनाही है।

सी ++ 11 में, एक प्रति निर्माता को हटाने तथ्य यह है कि एक वर्ग गैर copyable है व्यक्त करने के लिए सही तरीका है (जब तक कि बेशक यह समझ में आता है आप Track के सदस्य काम करता है, या के दोस्तों के लिए जाने के लिए Track, प्रतिलिपि बनाने के लिए Track ऑब्जेक्ट्स)।

5

एक कन्स्ट्रक्टर निजी बनाना मूल रूप से पुराने सी ++ में "हैक" था, क्योंकि यह एकमात्र तरीका था उपयोगकर्ताओं को उनका उपयोग करने से रोकें। delete विशेष सदस्य कार्यों की क्षमता केवल सी ++ 11 में पेश की गई थी, और यह कहना बेहतर और अधिक मूर्खतापूर्ण तरीका है कि एक वर्ग की प्रतिलिपि नहीं बनाई जा सकती है। चूंकि यह इरादे के बारे में स्पष्ट है।

निजी रचनाकारों के पास उनके उपयोग को पूरी तरह से मना करने के अलावा अन्य उपयोग हैं (उदाहरण के लिए उन्हें स्थैतिक वर्ग सदस्य कार्यों द्वारा बुलाया जा सकता है)। तो बस एक कन्स्ट्रक्टर निजी बनाना इरादे को बहुत अच्छी तरह से संवाद नहीं करता है, और परिणामी त्रुटि बहुत स्पष्ट नहीं है।

0

आपका पहला दृष्टिकोण कक्षा को खुद को कॉपी करने से रोकता नहीं है। इसे हल करने का पारंपरिक तरीका यह है कि इसे अनुपूरक छोड़ने के लिए कॉपी-कन्स्ट्रक्टर निजी और घोषित करें।

हालांकि, इसके साथ एक मुद्दा यह है कि इरादा स्पष्ट नहीं हो सकता है। कोड पढ़ने वाले किसी को यह समझ में नहीं आ रहा है कि एक अनाथ घोषित क्यों मौजूद है और गलती से इसे हटा सकता है। यदि बूस्ट आपके लिए उपलब्ध है तो टिप्पणियां boost::noncopyable से निजी रूप से विरासत में सहायता करने में सहायता कर सकती हैं।

दूसरा दृष्टिकोण इरादा स्पष्ट करता है और यदि आप सी ++ 11 का उपयोग कर सकते हैं तो आपको क्या पसंद करना चाहिए।

0

आपका पहला समाधान पाठक को बताता है कि कॉपी-कन्स्ट्रक्टर निजी है और इसका उपयोग नहीं किया जाना चाहिए। आपका दूसरा समाधान केवल C++ 11 में मान्य है। इस वजह से, मैं कहूंगा कि निजी पोर्टल का उपयोग करके अधिक पोर्टेबल और पठनीय कार्यान्वयन आपका पहला होगा।

0

यदि आप सी ++ 11 पर हैं, तो delete का उपयोग करें। कारण यह है कि यह कॉल स्पष्ट और इरादा स्पष्ट करता है। आप अभी भी गलती से एक निजी कन्स्ट्रक्टर (उदाहरण के लिए स्कॉप्स के प्रतिबंधित सेट में) का उपयोग कर सकते हैं, लेकिन कंपाइलर आपको हटाए गए कन्स्ट्रक्टर का उपयोग करने से रोक देगा।

निजी कन्स्ट्रक्टर का एक मुद्दा यह है कि कक्षा और मित्र अभी भी इसका उपयोग कर सकते हैं - यह परिणाम एक्सेस त्रुटियों में नहीं हैं लेकिन लिंक त्रुटियां हैं, जो कॉलसाइट पर वापस जाने के लिए मुश्किल हो सकती हैं।

यदि आपका आवश्यक toolchains का समर्थन नहीं करते नष्ट कंस्ट्रक्टर्स (= delete) (के रूप में अपने प्रश्न में देखा), तो आप इसे परिभाषित नहीं करना चाहिए - केवल यह घोषणा करते हैं और यह अपरिभाषित छोड़ देते हैं, जैसे: private: \n Track(const Track&);

0

में पहला मामला, आप अनिवार्य रूप से एक निजी प्रतिलिपि निर्माता घोषित कर रहे हैं और फिर कोई कार्यान्वयन नहीं कर रहे हैं। उन्हें निजी घोषित करके, गैर-सदस्य इसे कॉपी नहीं कर सकते हैं।

दूसरे मामले में, वाक्यविन्यास एक प्रतिलिपि बनाने से मना कर देता है। यह सी ++ मूल है।

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

आप केवल "= हटाएं" का उपयोग कर सकते हैं और स्पष्ट रूप से यह बता सकते हैं कि आप क्या करने का प्रयास कर रहे हैं।

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

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