मैं कॉपी कंस्ट्रक्टर में निजी चर का उपयोग क्यों कर सकता हूं?


88

मैंने सीखा है कि मैं एक निजी चर का उपयोग कभी नहीं कर सकता, केवल कक्षा में एक फ़ंक्शन के साथ। लेकिन फिर मैं इसे कॉपी कंस्ट्रक्टर में क्यों एक्सेस कर सकता हूं?

उदाहरण:

Field::Field(const Field& f)
{
  pFirst = new T[f.capacity()];

  pLast = pFirst + (f.pLast - f.pFirst);
  pEnd  = pFirst + (f.pEnd - f.pFirst);
  std::copy(f.pFirst, f.pLast, pFirst);
}

मेरी घोषणा:

private:
  T *pFirst,*pLast,*pEnd;

क्योंकि कॉपी कंस्ट्रक्टर डिफ़ॉल्ट रूप से एक क्लास सदस्य है, और इसलिए कुछ अन्य हैं।
DumbCoder

+ 53 / -0? इसके लिए किसने वोट किया? आप उन्हें कैसे कॉपी करेंगे? (आइए गैर-विकल्पों को डिबंक करें: प्रत्येक निजी सदस्य के लिए एक सार्वजनिक संदर्भ गटर बनाएं; फिर वे सभी निजी नहीं हैं। const&प्रत्येक के लिए एक सार्वजनिक या बाय-वैल्यू गेट्टर बनाएं ? फिर वे केवल 'राइट-प्राइवेट' हैं, & अपशिष्ट संसाधनों के लिए और गैर-प्रतिलिपि योग्य सदस्यों के लिए विफल।) मैं इस तरह के एक खाली प्रश्न की सफलता से चकित हूं, कॉपी-निर्माण के बारे में पूछ रहा हूं, जबकि इसका क्या अर्थ है, इसे पूरी तरह से नजरअंदाज करते हुए, और कोई भी उत्तर इसे नष्ट करने के लिए बुनियादी तर्क का उपयोग नहीं करता है। वे सूखी तकनीकी की व्याख्या करते हैं, लेकिन इस प्रश्न के एक नितांत सरल उत्तर का जवाब इस निमिष से है
अंडरस्कोर_ड

8
@underscore_d, "आप उन्हें और कैसे कॉपी करेंगे?" मेरी राय में एक बहुत ही अजीब प्रतिक्रिया है। यह जवाब देने जैसा है "गुरुत्वाकर्षण कैसे काम करता है?" "और चीजें कैसे नीचे गिरेंगी!" ऑब्जेक्ट स्तर के इनकैप्सुलेशन के साथ भ्रमित करने वाला वर्ग स्तर इनकैप्सुलेशन वास्तव में काफी सामान्य है। यह मजेदार है कि आप कैसे सोचते हैं कि यह एक बेवकूफ सवाल है और इसका जवाब स्पष्ट होना चाहिए। ध्यान रखें कि स्मॉलटाकल (निश्चित रूप से कट्टरपंथी ओओ भाषा) में एनकैप्सुलेशन वास्तव में ऑब्जेक्ट स्तर पर काम करने के लिए होता है।
एयरोबे नोव

@aioobe अच्छा बिंदु, धन्यवाद। मेरी टिप्पणी थोड़े अतिवादी है - शायद उस दिन कॉफी मशीन टूट गई थी। मैं आपकी ओर इशारा करते हुए सराहना करता हूं कि यह प्रश्न क्यों लोकप्रिय होगा, विशेष रूप से अन्य (और शायद अधिक) ओओ भाषाओं से उन लोगों के बीच। वास्तव में, यह तर्कपूर्ण है कि मेरी टिप्पणी "ब्लिंकर" थी, क्योंकि मैं किसी ऐसे व्यक्ति के दृष्टिकोण से लिख रहा था जो ज्यादातर सी ++ में कार्यक्रम करता है। इसके अलावा, कि गुरुत्वाकर्षण सादृश्य प्यार!
अंडरस्कोर

जवाबों:


33

IMHO, मौजूदा उत्तर एक खराब काम करते हैं जो "क्यों" की व्याख्या करते हैं - जो व्यवहार के वैध को दोहराते हुए बहुत अधिक ध्यान केंद्रित करता है। "एक्सेस संशोधक वर्ग स्तर पर काम करते हैं, न कि वस्तु स्तर पर।" - हां लेकिन क्यों?

यहाँ अतिव्यापी अवधारणा यह है कि यह प्रोग्रामर (ओं) को डिज़ाइन करना, लिखना और एक वर्ग को बनाए रखना है जो (हैं) से अपेक्षित है कि वे ओओ इनकैप्सुलेशन को समझें और इसके कार्यान्वयन को समन्वित करें। इसलिए, यदि आप लिख रहे हैं, तो आप इसे class Xएन्कोडिंग नहीं X xकर सकते हैं कि किसी व्यक्तिगत वस्तु का उपयोग कोड के साथ कैसे किया जा सकता है, लेकिन यह भी कैसे:

  • व्युत्पन्न वर्ग इसके साथ बातचीत करने में सक्षम हैं (वैकल्पिक रूप से शुद्ध आभासी कार्यों और / या संरक्षित पहुंच के माध्यम से), और
  • अलग-अलग Xऑब्जेक्ट आपके डिज़ाइन से पोस्ट-कंडीशंस और इन्वर्टर को सम्मानित करते हुए इच्छित व्यवहार प्रदान करने में सहयोग करते हैं।

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

विशेष रूप से, ये ऑपरेशन निजीकृत उपयोग का लाभ उठाने के लिए काम कर सकते हैं जैसे:

  • (कॉपी कंस्ट्रक्टर) एक प्रारंभिक सूची में "rhs" (दाएं हाथ की ओर) ऑब्जेक्ट के एक निजी सदस्य का उपयोग करते हैं, ताकि डिफ़ॉल्ट-निर्माण के बजाय एक सदस्य चर स्वयं कॉपी-निर्माण किया जाता है (यदि कानूनी भी है) तो असाइन किया गया (फिर से,) अगर कानूनी है)
  • शेयर संसाधन - फाइल हैंडल, साझा मेमोरी सेगमेंट, shared_ptrसंदर्भ डेटा के लिए आदि।
  • auto_ptr<>निर्माणाधीन वस्तु के स्वामित्व वाली "चाल" जैसे चीजों का स्वामित्व लें
  • निजी "कैश", अंशांकन, या राज्य के सदस्यों को खरोंच से उन्हें पुनर्जीवित किए बिना एक बेहतर उपयोग करने योग्य स्थिति में नई वस्तु के निर्माण के लिए आवश्यक प्रतिलिपि बनाएँ
  • कॉपी / एक्सेस डायग्नोस्टिक / ट्रेस जानकारी को कॉपी किए जा रहे ऑब्जेक्ट में रखा गया है जो अन्यथा सार्वजनिक एपीआई के माध्यम से सुलभ नहीं है, लेकिन बाद के कुछ अपवाद ऑब्जेक्ट या लॉगिंग द्वारा उपयोग किया जा सकता है (उदाहरण के लिए समय / परिस्थितियों के बारे में जब "मूल" गैर-कॉपी-निर्मित उदाहरण निर्माण किया गया था)
  • कुछ डेटा की अधिक कुशल प्रतिलिपि बनाएँ: उदाहरण के लिए वस्तुओं में कोई unordered_mapसदस्य हो सकता है, लेकिन सार्वजनिक रूप से केवल एक्सपोज़र begin()और end()पुनरावृत्तियाँ - सीधे पहुँच के साथ size()आप reserveतेज़ी से प्रतिलिपि बनाने की क्षमता प्राप्त कर सकते हैं ; बदतर अभी भी अगर वे केवल बेनकाब at()और insert()और नहीं तो throw....
  • माता-पिता / समन्वय / प्रबंधन वस्तुओं पर संदर्भों की प्रतिलिपि बनाएँ जो क्लाइंट कोड के लिए अज्ञात या केवल-लेखन हो सकते हैं

2
मुझे लगता है कि सबसे बड़ा 'क्यों' यह है कि यह जांचने के लिए एक जबरदस्त रनटाइम ओवरहेड होगा कि क्या this == otherहर बार जब आप एक्सेस other.xकरते हैं तो आपको यह देखना होगा कि एक्सेस संशोधक ऑब्जेक्ट स्तर पर काम करते हैं या नहीं।
18obe को aioobe

2
@aioobe मुझे लगता है कि आपका उत्तर रास्ता, रास्ता अधिक प्रमुख होना चाहिए। Whilel टोनी का जवाब वास्तव में अच्छा और वैचारिक है, अगर मैं एक सट्टेबाजी का आदमी था, तो मैं शर्त लगा सकता हूं कि आपका जवाब पसंद के लिए वास्तविक ऐतिहासिक कारण है। न केवल यह अधिक उत्कृष्ट है, बल्कि यह बहुत सरल भी है। Bjarne के लिए एक बड़ा सवाल होगा!
निर फ्राइडमैन

मैं अपने जवाब में चिह्नित किया है, क्योंकि यह पृष्ठभूमि बताते हैं;)
demonking

@demonking, मुझे लगता है कि इस उत्तर में दिए गए कारण कवर करते हैं कि निजी डेटा को अन्य वस्तुओं के लिए खुला रहने देना सुविधाजनक क्यों है । लेकिन एक्सेस मॉडिफायर डेटा को "खुले तौर पर" पर्याप्त बनाने के लिए नहीं हैं। वे केवल एनकैप्सुलेशन के लिए डेटा को पर्याप्त रूप से बंद करने के लिए हैं। ( सुविधा के लिहाज से यह बेहतर होगा यदि निजी चर सार्वजनिक हों!) मैंने अपने उत्तर को एक खंड के साथ अद्यतन किया है जो मुझे लगता है कि वास्तविक क्यों बेहतर है ।
aioobe

@aioobe: वर्ष टिप्पणियाँ, लेकिन वैसे भी ... "चेक अगर this == otherहर बार जब आप का उपयोग other.x" - बिंदु याद करते हैं - अगर other.xकेवल रनटाइम पर स्वीकार कर लिया गया जब बराबर करने के लिए this.x, वहाँ बहुत सूचक लेखन नहीं होगा other.xपहली जगह में; संकलक आप if (this == other) ...this.x...जो कुछ भी करने जा रहे हैं उसके लिए लिखने के लिए बाध्य कर सकते हैं। आपका "सुविधा (और भी अधिक है, तो निजी चर सार्वजनिक थे)" जिस तरह से मानक के परिभाषित किया गया है प्रतिबंधात्मक अनुमति देने के लिए पर्याप्त - गर्भाधान भी बिंदु याद करते हैं उचित कैप्सूलीकरण, लेकिन नहीं अनावश्यक रूप से असुविधाजनक।
टोनी डेलरो

108

पहुँच संशोधक वर्ग स्तर पर काम करते हैं , न कि वस्तु स्तर पर

अर्थात्, एक ही वर्ग की दो वस्तुएँ एक-दूसरे के निजी डेटा तक पहुँच सकती हैं।

क्यों:

मुख्य रूप से दक्षता के कारण। यह जांचने के लिए एक गैर-नगण्य रनटाइम ओवरहेड होगा, यदि this == otherआप हर बार एक्सेस करते हैं other.xकि आपको एक्सेस मोडिफायर ऑब्जेक्ट स्तर पर काम करना है या नहीं।

यदि आप इसे स्कोपिंग के संदर्भ में सोचते हैं, तो यह भी एक प्रकार का शब्दार्थिक तर्क है: "निजी चर को संशोधित करते समय मुझे कोड का कितना बड़ा हिस्सा ध्यान में रखना चाहिए?" - आपको पूरी कक्षा के कोड को ध्यान में रखने की आवश्यकता है, और यह ऑर्थोगोनल है जिससे ऑब्जेक्ट रनटाइम में मौजूद हैं।

और कॉपी कंस्ट्रक्टर और असाइनमेंट ऑपरेटरों को लिखते समय यह अविश्वसनीय रूप से सुविधाजनक है।


35

आप एक वर्ग के निजी सदस्यों को कक्षा के भीतर से एक्सेस कर सकते हैं, यहां तक ​​कि दूसरे उदाहरण के भी।


10

उत्तर को समझने के लिए, मैं आपको कुछ अवधारणाओं को याद दिलाना चाहूंगा।

  1. कोई फर्क नहीं पड़ता कि आप कितनी वस्तुओं का निर्माण करते हैं, उस वर्ग के लिए स्मृति में केवल एक फ़ंक्शन की एक प्रति है। इसका मतलब है कि फ़ंक्शन केवल एक बार बनाए जाते हैं। हालाँकि चर वर्ग के प्रत्येक उदाहरण के लिए अलग-अलग होते हैं।
  2. this जब कहा जाता है, तो सूचक को प्रत्येक फ़ंक्शन में पास किया जाता है।

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

उम्मीद है कि यह आपके प्रश्न का उत्तर देगा।


6

कॉपी कंस्ट्रक्टर क्लास 'मेंबर फंक्शन है और जैसे-जैसे क्लास' डेटा मेंबर्स तक पहुंच होती है, यहां तक ​​कि जिन्हें 'प्राइवेट' भी घोषित किया जाता है।


3
जैसा कि कोई है जो भाषा जानता है, मैं समझता हूं कि आपका क्या मतलब है। हालाँकि, अगर मैं भाषा नहीं जानता था, तो मुझे लगता था कि आप सिर्फ मेरे लिए सवाल दोहरा रहे थे।
सैन जैसिंटो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.