हमें निजी सदस्यों को हेडर में रखने की आवश्यकता क्यों है?


62

निजी चर एक वर्ग के उपयोगकर्ता के लिए जटिलता और कार्यान्वयन विवरण छिपाने का एक तरीका है। यह बल्कि एक अच्छी सुविधा है। लेकिन मुझे समझ में नहीं आता है कि c ++ में हमें उन्हें एक क्लास के हेडर में डालने की आवश्यकता क्यों है। मैं इसे करने के लिए दो कष्टप्रद नीचे देख रहा हूं:

  • यह उपयोगकर्ता से हेडर को बंद कर देता है
  • यह सभी क्लाइंट पुस्तकालयों के पुनर्संयोजन के लिए मजबूर करता है जब भी आंतरिक को संशोधित किया जाता है

क्या इस आवश्यकता के पीछे कोई वैचारिक कारण है? क्या केवल संकलक का काम आसान करना है?


आप हेडर में एक खाली संरचना की घोषणा कर सकते हैं, लेकिन तब आप केवल इस तरह के ढांचे को पॉइंटर्स का उपयोग कर सकते हैं जब आप इसका उपयोग करते हैं (और आप एक आवंटित नहीं कर सकते हैं)
शाफ़्ट फ्रीक

3
@ratchetfreak: नहीं, खाली ( struct foo{};) की अनुमति नहीं है, लेकिन आगे की घोषणाएं ( struct foo;) हैं।
एमएसलटर्स

@ स्तनधारियों का यही मतलब है
शाफ़्ट फ्रैट

1
मुझे एक नकारात्मक पहलू जोड़ने दें: * .h फ़ाइल में निजी फ़ंक्शन हेडर लिखना समय की भारी बर्बादी है। (एक पल के लिए दोस्त कक्षाएं भूल जाते हैं)
जॉनी

जवाबों:


68

ऐसा इसलिए है क्योंकि C ++ कंपाइलर को तात्कालिकता पर सही मात्रा में मेमोरी आवंटित करने के लिए कक्षा के वास्तविक आकार का पता होना चाहिए। और आकार में सभी सदस्य, निजी भी शामिल हैं।

इससे बचने का एक तरीका पिंपल मुहावरे का उपयोग करना है , जिसे हर्ब सटर ने अपने गुरु की वीक सीरीज़ # 24 और # 28 में समझाया है ।

अपडेट करें

वास्तव में, यह (या अधिक सामान्यतः, हेडर / सोर्स फाइल डिस्टिंक्शन और #includeएस) C ++ में एक प्रमुख बाधा है, सी। बैक से विरासत में मिला है। C ++ C को बनाया गया था, बड़े पैमाने पर सॉफ्टवेयर विकास के साथ अभी तक कोई अनुभव नहीं था, जहां यह वास्तविक समस्याएं पैदा करने लगता है। तब से सीखे गए सबक नई भाषाओं के डिजाइनरों द्वारा ध्यान में रखे गए थे, लेकिन C ++ पिछड़ी अनुकूलता आवश्यकताओं से बंधी है, जिससे इस तरह के मूलभूत मुद्दे को भाषा में संबोधित करना वास्तव में कठिन हो जाता है।


क्या इस तरह की जानकारी केवल कक्षा के पुस्तकालय में निहित नहीं है? क्या इसे लिंक करने के लिए उपयोग किया जाता है?
साइमन बर्गोट

@ साइमन, "क्लास लाइब्रेरी" से आपका क्या तात्पर्य है?
पेटर टॉर्क

मेरा मतलब है कि क्लास की परिभाषा और तरीकों से युक्त ऑब्जेक्ट फ़ाइलों का संग्रह
सिमोन बर्गोट

7
जब C ++ बनाया गया था, उस समय AT & T / Bell Labs (Stroustrups नियोक्ता) को निश्चित रूप से बड़े पैमाने पर C विकास का अनुभव था। उनका 5ESS फोन स्विच सॉफ्टवेयर उस समय का था जो शायद दुनिया का सबसे बड़ा एकल कार्यक्रम था। OO के बारे में शुरुआती विचार पहले से ही उस कोड बेस में दिखाई दे रहे हैं, और Cfront ने उन तकनीकों की नकल की। हालांकि, की धारणा privateअधिक आधुनिक है।
एमएसलटर्स

1
सी में, आप बस एक पुस्तकालय समारोह में आवंटनकर्ता डालेंगे; ग्राहक ऐसी संरचना को आवंटित करने में सक्षम नहीं होगा। यह ओवरहेड को थोड़ा बढ़ाता है, लेकिन कोड को संस्करणों के लिए तुच्छ बनाता है, इसलिए यह अक्सर सार्थक होता है। हालाँकि, यह एक कोड शैली की ओर ले जाता है जो कि C ++ के साथ देखे जाने से बहुत अलग है।
डोनल फैलो

15

कंपाइलर के लिए क्लास डेफिनिशन का उपयोग करने के लिए क्लास डेफिनेशन को मेमोरी में एक समान लेआउट बनाने के लिए पर्याप्त होना चाहिए। उदाहरण के लिए, कुछ इस तरह दिया गया:

class X { 
    int a;
public:
    int b;
};

कंपाइलर में आमतौर aपर ऑफसेट 0 और bऑफसेट पर होगा 4। यदि संकलक ने इसे इस प्रकार देखा:

class X { 
public:
    int b;
};

यह "सोचना" bहोगा जो ऑफसेट के बजाय ऑफसेट 0 पर होना चाहिए। जब ​​उस परिभाषा bका उपयोग करते हुए कोड को सौंपा गया है , तो पहली परिभाषा का उपयोग करने वाला कोड aसंशोधित हो जाएगा , और इसके विपरीत।

कक्षा के निजी भागों में परिवर्तन करने के प्रभावों को कम करने का सामान्य तरीका आमतौर पर पिंपल मुहावरा कहा जाता है (जिसके बारे में मुझे यकीन है कि Google जानकारी का एक बड़ा हिस्सा दे सकता है)।


1
मैं एक डिजाइन निर्णय के बारे में पूछ रहा हूं। बेशक आपको भाषा के काम करने के लिए कहीं न कहीं निजी सदस्य की घोषणा करनी होगी। लेकिन यह हेडर में क्यों होना चाहिए और अधिक निजी स्थान पर नहीं होना चाहिए?
साइमन बर्गोट

7
@ साइमन: हेडर सभी कंपाइलर यह बताने के लिए देखते हैं कि क्लास / स्ट्रक्चर कैसा दिखता है। C ++ में मॉड्यूल की तरह कुछ जोड़ने की चर्चा हुई है, जो उस तरह के डेटा को थोड़ा अधिक छिपाएगा, लेकिन अभी तक इसे मंजूरी नहीं दी गई है (हालांकि यह पूरी तरह से या तो नहीं गिराया गया है)।
जेरी कॉफ़िन

3
फिर भी, एक तुच्छ नियम ऐसे "। Cpp-परिभाषित" निजी सदस्यों को अंतिम रूप से आवंटित करने के लिए होगा। इसका मतलब है कि सार्वजनिक और "सामान्य" निजी सदस्यों के वंशज उन पर निर्भर नहीं होंगे। IMO असली कारण यह है कि आप इस तरह के वर्ग से विरासत में नहीं मिल सकते हैं, क्योंकि व्युत्पन्न भाग को उन निजी सदस्यों का भी पालन करना होगा।
12

3

कई संभावित कारण हैं। जबकि निजी सदस्यों को अधिकांश अन्य वर्गों द्वारा एक्सेस नहीं किया जा सकता है, फिर भी उन्हें मित्र वर्गों द्वारा एक्सेस किया जा सकता है। इसलिए कम से कम इस मामले में उन्हें हेडर की आवश्यकता हो सकती है, इसलिए मित्र वर्ग देख सकते हैं कि वे मौजूद हैं।

आश्रित फ़ाइलों का पुनर्संयोजन आपकी सम्मिलित संरचना पर निर्भर हो सकता है। .Hp फ़ाइलों को किसी अन्य शीर्षलेख के बजाय .cpp फ़ाइल में शामिल करना कुछ मामलों में पुनर्मिलन की लंबी श्रृंखला को रोक सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.