2012-01-29 10 views
11

से गुजर "अक्षम" कॉपी करने और निजी प्रतिलिपि निर्माता और असाइनमेंट ऑपरेटर को परिभाषित करते हुए मेरी वस्तुओं के लिए बताए:काम की अनुमति नहीं दी है और मैं क्या समझ मैं करने में सक्षम हूँ से मूल्य

class MyClass 
{ 
private: 
    MyClass(const MyClass& srcMyClass); 
    MyClass& operator=(const MyClass& srcMyClass); 
} 

लेकिन इस का उपयोग क्या है?
क्या यह एक बुरा अभ्यास माना जाता है?

यदि आप स्थिति का वर्णन कर सकते हैं तो मैं सराहना करता हूं, जिसमें यह असाइनमेंट के लिए उचित/उपयोगी होगा और इस तरह से कन्स्ट्रक्टर कॉपी करेगा।

+1

एक सिंगलटन एक उदाहरण होगा। –

उत्तर

11

यह उपयोगी है जब आपके ऑब्जेक्ट की प्रतिलिपि बनाने के लिए यह समझ में नहीं आता है। यह निश्चित रूप से बुरा अभ्यास नहीं माना जाता है।

उदाहरण के लिए, यदि आपके पास एक नेटवर्क कनेक्शन का प्रतिनिधित्व करने वाली कक्षा है, तो उस ऑब्जेक्ट को कॉपी करना अर्थपूर्ण नहीं है। एक और बार जब आप कक्षा को गैर-लोकप्रिय होना चाहते हैं तो यह है कि यदि आपके पास एक मल्टीप्लेयर गेम में एक खिलाड़ी का प्रतिनिधित्व करने वाला वर्ग था। ये दोनों कक्षाएं ऐसी चीजों का प्रतिनिधित्व करती हैं जिन्हें वास्तविक दुनिया में कॉपी नहीं किया जा सकता है, या जो प्रतिलिपि बनाने के लिए समझ में नहीं आता है (एक व्यक्ति, एक कनेक्शन)।

इसके अलावा, यदि आप सिंगलटन को लागू करने की कोशिश कर रहे हैं, तो ऑब्जेक्ट्स को गैर-प्रतिलिपि बनाने के लिए यह मानक प्रक्रिया है।

+0

धन्यवाद, यह समझ में आता है। असाइनमेंट ऑपरेटर के बारे में क्या? – LihO

+3

@LihO आम तौर पर यदि आप किसी को अक्षम करते हैं तो आप दूसरे को अक्षम करते हैं। यदि आप असाइनमेंट ऑपरेटर को अक्षम नहीं करते हैं, तो आप यह कर सकते हैं: 'MyClass a, b; ए = बी; 'और यदि आप कॉपी कन्स्ट्रक्टर को अक्षम नहीं करते हैं तो आप' MyClass b; MyClass a (बी); 'तो यदि आप दोनों को अक्षम नहीं करते हैं, तो आप दूसरे को अक्षम कर सकते हैं। –

+0

हाँ, अब मुझे मिल गया। – LihO

0

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

2

यह एक बहुत ही आम प्रथा है। ऐसे कई उदाहरण हैं जहां प्रतिलिपि उचित नहीं है।

मान लें कि आपका ऑब्जेक्ट एक खुली सर्वर-साइड सॉकेट (यानी एक आने वाला नेटवर्क कनेक्शन) का प्रतिनिधित्व करता है; उस वस्तु की एक प्रति बनाने के अर्थशास्त्र क्या होगा?

5

आम तौर पर संसाधन का प्रबंधन करने वाली किसी भी कक्षा को बोलने के लिए कोई भी प्रतिलिपि नहीं होनी चाहिए या विशिष्ट प्रति अर्थशास्त्र होना चाहिए। बातचीत भी सच है: कोई भी वर्ग जो गैर-प्रतिलिपि योग्य है या विशेष प्रतिलिपि की आवश्यकता है, संसाधन संसाधन का प्रबंधन कर रहा है। अभ्यास में सी ++ लिंगुआ में "संसाधन प्रबंधित करें" का अर्थ स्मृति में कुछ जगह, या किसी नेटवर्क या डेटाबेस से कनेक्शन के लिए, या किसी फ़ाइल को हैंडल या पूर्ववत लेनदेन के लिए ज़िम्मेदार है।

संसाधन प्रबंधन काफी सारे उदाहरणों को कैप्चर करता है। ये जिम्मेदारियां हैं जो एक उपसर्ग ऑपरेशन, एक प्रत्यय संचालन और संभवतः बीच में कुछ क्रियाएं लेती हैं। मेमोरी प्रबंधन, उदाहरण के लिए, एक मेमोरी एड्रेस को एक हैंडल प्राप्त करना शामिल है जिसे हम प्रबंधित करेंगे, शायद उस मेमोरी के साथ गड़बड़ कर सकते हैं, और अंततः हैंडल को छोड़ दें (क्योंकि अगर आप कुछ प्यार करते हैं, तो इसे मुक्त करें)।

template<typename T> 
struct memory { 
    memory(T const& val = T()) : p(new T(val)) { } 
    ~memory() { delete p } 
    T& operator*() const { return *p; } 
private: 
    T* p; 
}; 

// ... 
{ 
    memory<int> m0; 
    *m0 = 3; 
    std::cout << *m0 << '\n'; 
} 

यह memory वर्ग लगभग सही है: यह स्वचालित रूप से अंतर्निहित स्मृति स्थान प्राप्त कर लेता है और स्वचालित रूप से इसे जारी करता है, एक अपवाद कुछ समय के बाद वह अपने संसाधन का अधिग्रहण प्रसारित भले ही। लेकिन इस परिदृश्य पर विचार करें:

{ 
    memory<double> m1(3.14); 
    memory<double> m2(m1); // m2.p == m1.p (do you hear the bomb ticking?) 
} 

क्योंकि हम memory के लिए विशेष प्रतिलिपि अर्थ विज्ञान नहीं प्रदान की थी, संकलक अपनी एक प्रतिलिपि निर्माता प्रदान करता है और काम की नकल। ये गलत बात करते हैं: m2 = m1 का अर्थ है m2.p = m1.p, जैसे कि दो पॉइंटर्स एक ही पते पर इंगित करते हैं।यह गलत है क्योंकि जब m2 दायरे से बाहर चला जाता है कि यह एक अच्छा जिम्मेदार वस्तु की तरह अपने संसाधन नहीं रह जाती और जब m1 तो दायरे से बाहर चला जाता है यह भी अपने संसाधन को मुक्त कर देते, कि एक ही संसाधन m2 पहले से ही मुक्त कर दिया गया है, एक डबल हटाना पूरा - एक कुख्यात अपरिभाषित व्यवहार परिदृश्य। इसके अलावा, सी ++ में किसी ऑब्जेक्ट की प्रतियों को ध्यान में रखकर बहुत आसान है: एक फ़ंक्शन मूल्य के आधार पर अपना पैरामीटर ले रहा है, उसके पैरामीटर को मान द्वारा वापस कर रहा है, या इसके पैरामीटर को संदर्भ द्वारा ले रहा है, लेकिन उसके बाद दूसरा फ़ंक्शन कॉल कर रहा है जो स्वयं लेता है (या रिटर्न) मूल्य द्वारा पैरामीटर ... यह सिर्फ ग्रहण करने के लिए है कि चीजें कॉपी हो करने की कोशिश करेंगे आसान है।

यह सब

कहना है कि जब एक वर्ग 'किशमिश एक संसाधन प्रबंध कर रहा है तो आप तुरंत पता होना चाहिए कि आप नकल संभाल करने की जरूरत है। आप तय करना चाहिए

  • आप नकल का समर्थन है, जबकि आप यह तय करें कि नकल का अर्थ है:, संसाधन के सुरक्षित बंटवारे अंतर्निहित संसाधन की एक गहरी प्रतिलिपि प्रदर्शन इसलिए कोई साझा करने जो भी है, या copy-on-write में के रूप में दो दृष्टिकोण के संयोजन या आलसी प्रतिलिपि। जो भी रास्ता आप चुनते हैं आप एक विशेष प्रतिलिपि निर्माता और एक प्रति असाइनमेंट ऑपरेटर प्रदान करने के लिए की आवश्यकता होगी।
  • या आप संसाधन की नकल किसी भी प्रकार का, जिस स्थिति में आप प्रतिलिपि निर्माता और प्रति असाइनमेंट ऑपरेटर को निष्क्रिय समर्थन नहीं करते।

मैं अब तक जाऊंगा और कहूंगा कि संसाधन प्रबंधन एकमात्र ऐसा मामला है जहां आप प्रतिलिपि अक्षम करते हैं या विशिष्ट प्रति semantics प्रदान करते हैं। यह The Rule of Three पर एक और परिप्रेक्ष्य है।

0

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

भी इस जाँच: Singleton Class in C++

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