Java C हेडर के उपयोग की अनुमति C ++ में क्यों नहीं देता


18

मेरा एक प्रश्न है कि मुझे निम्नलिखित उत्तर को छोड़कर कोई उत्तर नहीं मिला जो मेरी आवश्यकताओं को पूरा नहीं करता है:

"क्योंकि जेम्स गोसलिंग नहीं चाहते थे"

मुझे पता है कि जावा में इंटरफेस (केवल शुद्ध आभासी फ़ंक्शन, कोई विशेषता नहीं) हो सकते हैं, लेकिन यह कक्षा परिभाषाओं के समान सटीक नहीं है।


14
क्या कारण है कि आप उन्हें चाहते हैं?

19
तलवारबाजी के लिए अधिक समय देने के लिए;)
dan04

6
मुझे लगता है कि ज्यादातर C ++ डेवलपर्स को 40 साल पुराने टेक्स्ट रिप्लेसमेंट इंजन से छुटकारा पाना पसंद होगा, जो हर cpp फ़ाइल के लिए सैकड़ों kLoC की नकल करता है, जिससे C ++ का लंबा संकलन समय होता है। वास्तव में C ++ 11 के लिए एक उचित मॉड्यूल प्रणाली पर विचार किया गया था, लेकिन समय की कमी के कारण गिरा दिया गया। मुझे लगता है कि यह फिर से आ जाएगा, हालांकि।
sbi

मुझे लगता है कि यह फिर से आ जाएगा, हालांकि। वास्तव में WG21 (ISO C ++ वर्किंग ग्रुप) के पास "मॉड्यूल" अवधारणा को और अधिक विकसित करने / विकसित करने के उद्देश्य से एक अध्ययन समूह है: SG2 "मॉड्यूल"। बहुत बुरा यह वर्तमान स्थिति निष्क्रिय है
मैक्स Truxa

जवाबों:


46

निम्नलिखित उत्तर जो मेरी आवश्यकताओं को पूरा नहीं करते हैं: "क्योंकि जेम्स गोस्लिंग नहीं करना चाहते थे।"

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

से जावा भाषा पर्यावरण श्वेत पत्र की धारा 2.2.1 :

जावा में लिखा गया सोर्स कोड सरल है। कोई प्रीप्रोसेसर, कोई #define और संबंधित क्षमताएं नहीं हैं, कोई टाइपफ़ेड नहीं है, और उन विशेषताओं को अनुपस्थित करता है, जिन्हें अब हेडर फ़ाइलों की कोई आवश्यकता नहीं है। शीर्ष लेख फ़ाइलों के बजाय, जावा भाषा स्रोत फाइलें अन्य वर्गों और उनके तरीकों की परिभाषा प्रदान करती हैं।

अनावश्यक परिभाषाएँ, फाइलों को सिंक में रखना, परस्पर विरोधी परिभाषाएँ, छिपी हुई परिभाषाएँ - इनमें से कोई भी जावा में नहीं होती है, क्योंकि आप हेडर नहीं बनाते हैं। यदि आप एक नंगे वर्ग की परिभाषा देखना चाहते हैं, तो आप सीधे एक .java फ़ाइल से एक उत्पन्न कर सकते हैं - उदाहरण के लिए अधिकांश IDEs आपको साइडबार में एक वर्ग की संरचना दिखाएंगे, जो एक ही चीज़ पर निर्भर करती है।


6
आपके उत्तर के लिए धन्यवाद, फिर, हेडर ने उस वजह से और अधिक समस्याएं पैदा कीं: निरर्थक परिभाषाएं, फाइलों को सिंक में रखना, परस्पर विरोधी परिभाषाएं, छिपी हुई परिभाषाएं। क्या इसीलिए इसकी अनुमति नहीं दी गई?
इटियेन नोएल

2
ध्यान दें कि अगली C ++ Commitee मीटिंग्स के बारे में बहुत सारी बाते हैं क्योंकि वे एक नए "मॉड्यूल" सिस्टम पर विचार करेंगे जो एक सरल और अधिक कुशल प्रणाली होगी, जिसमें शामिल हैं (जावा, C # आदि पैकेजों के साथ कुछ समानताएं) लेकिन रेट्रो के साथ असंगत। यह कहना है कि एक बेहतर संकलन प्रणाली, कम से कम सिद्धांत रूप में, C ++ संकलन को बेहतर / अधिक कुशल बनाने के लिए उपयोग किया जा सकता है। गोसलिंग सही था मुझे लगता है, और सी ++ को वैसे भी सिस्टम को ठीक करने का एक तरीका खोजना होगा।
क्लेम

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

1
@kevin: हालांकि यह आमतौर पर बहुत अधिक लागत के बिना सब कुछ बस पुनर्निर्माण करने के लिए संभव है। सी ++ के विपरीत (लेकिन पृथ्वी पर लगभग हर दूसरी संकलित भाषा की तरह) जावा सिर्फ इतना समय नहीं लेता है कि आंशिक संकलन आपके विकास वर्कफ़्लो का एक बहुत ही अनुकूल अनुकूलन है।
डोनल फेलो

1
@ डोनल: यह सच है कि जावा बहुत जल्दी संकलन करता है, लेकिन मुझे यह अनुमान लगाने से नफरत है कि मुझे पूर्ण पुनरावृत्ति करनी चाहिए या नहीं। बिल्ड सिर्फ काम करना चाहिए, हर बार।
केविन क्लाइन

16

अलग फ़ाइलों में वर्ग परिभाषाएँ और घोषणाएँ करने के लिए C ++ में कोई वास्तविक आवश्यकता नहीं है। इसका सिर्फ इतना मतलब है कि आप कम से कम C दिनों में वापस आ सकते हैं, कोड के सिंगल टॉप-बॉटम स्कैन में पार्स करें। यादृच्छिक अभिगम भंडारण के बिना मशीनों पर यह एक बड़ी बात थी!

हेडर रखने से आपको स्रोत कोड प्रकट करने की आवश्यकता के बिना हेडर की आपूर्ति करके अपने कोड लाइब्रेरी में इंटरफ़ेस प्रकाशित करने की अनुमति मिलती है। दुर्भाग्य से सी ++ में आपको निजी डेटा सदस्यों को भी प्रकट करना होगा जिसके कारण पिंपल के आतंक की तरह समाधान हो गया है ।

वहाँ एक C ++ वातावरण बनाने की कोशिश की गई है जहाँ सब कुछ एक डेटाबेस प्रकार की संरचना में संग्रहीत किया गया था और कोई फाइल नहीं है, लेकिन यह पकड़ में नहीं आया।


मुझे पता है कि, लेकिन कम से कम आप इसे C ++ में जावा में नहीं कर सकते हैं; यह मेरी मुख्य पूछताछ थी। जवाब के लिए धन्यवाद।
इटियेन नोएल

14

की वजह से सूखी सिद्धांत। जावा में, पैकेज (या कक्षा) में कक्षाओं का उपयोग करने के लिए आवश्यक जानकारी .class फ़ाइल के अंदर समाहित है। एक ही जानकारी वाले अलग हेडर फाइल बनाने से इसे दो जगहों पर दोहराना होगा।


दुर्भाग्य से, आप अक्सर इसे दोहराना चाहते हैं - wsdl फ़ाइलों के बारे में सोचें, आईडीएल फाइलें आदि। एक उस इंटरफ़ेस का वर्णन करता है जिसका आप उपयोग कर सकते हैं, और दूसरी फ़ाइल में कार्यान्वयन शामिल है। C ++ हेडर इंटरफ़ेस (खराब) इंटरफ़ेस परिभाषाएँ हैं।
22

6

हर भाषा में - अंतिम बाइनरी कोड बनाने के लिए दो चरण होते हैं - संकलन और लिंकिंग (निश्चित रूप से, वहाँ लोड हो रहा है लेकिन इसका यहाँ बहुत प्रभाव नहीं है)। संकलन के समय किसी को उचित स्थान पर केवल हुक (कार्यों के विनिर्देशन जिसे कहा जाएगा) कहा जाना चाहिए। दोनों वास्तविक कोड उपलब्ध होने पर लिंकर वास्तव में उनका साथ देता है। अभी तक C ++ और Java में कोई अंतर नहीं है।

वहाँ है तथापि के लिए सी ++ घोषणा और परिभाषा अलग है करने के लिए एक की जरूरत है,,। यदि आप हेडर में कार्यान्वयन को बनाए रखते हैं, और यदि हेडर फ़ाइल बदलता है, तो कोड जो इसके साथ जुड़ा हुआ है, उसे पुनः प्राप्त करने की आवश्यकता है। जैसे कि यदि परिभाषा अलग फ़ाइल में है, तो कोड को केवल पुनः लिंक करने की आवश्यकता है।

यह समझें कि C ++ में स्थैतिक लिंकिंग का विकल्प है, जिसका अर्थ है कि कॉलिंग एप्लिकेशन के साथ ऑब्जेक्ट कोड तय हो गया है। कृपया ध्यान दें कि C और C ++ दोनों में, हेडर फ़ाइल में प्रोग्रामिंग करना या #include करना भी अमान्य नहीं है। इसका केवल यह अर्थ है कि आपको इन ऑब्जेक्ट फ़ाइलों के साथ लिंक करने के तरीके के बारे में परेशान करने की आवश्यकता है।

जावा की स्थिति बहुत अलग है। प्रत्येक वर्ग फ़ाइल .class फ़ाइल के साथ संकलित की जाती है। वास्तव में, कोलर क्लास फ़ंक्शन संकलन की आवश्यकता होती है जो कि .class फ़ाइल में हेडर सेक्शन के रूप में प्रस्तुत किया जाता है। हालाँकि, Java फाइनल में लिंकिंग केवल रनटाइम (वर्चुअल मशीन) के अंदर ही की जाती है, जो कि क्लास फाइल के बाइट कोड के विनिर्देशन के साथ होती है।

यह और यह देखें


4

प्रभावी रूप से इंटरफेस और शामिल हैं हेडर; परिभाषाएँ इसलिए बायनेरिज़ के समान हैं, और सिंक्र के बाहर नहीं हो सकती हैं। यह जावा में सर्वश्रेष्ठ डिजाइन निर्णयों में से एक है, लेकिन यह एक छोटी सी झुंझलाहट है कि कॉम्पैक्टनेस और स्थिरता के लिए इन घोषणाओं को बंडल करने का कोई तरीका नहीं है।


1

इसमें शामिल होने का एक अच्छा कारण यह है कि जिस कोड को आप पुन: उपयोग करना चाहते हैं (जैसे सामान्य परिभाषाएँ) किसी दिए गए प्रोजेक्ट के लिए विशिष्ट कोड को अलग करना चाहते हैं। जावा चाहता है कि आप प्रति फ़ाइल केवल एक वर्ग या इंटरफ़ेस निर्दिष्ट करें और इसमें ज्यादातर शामिल हेडर की आवश्यकता कम हो जाती है - क्योंकि आप साझा किए गए भागों को पहले से ही अपनी फ़ाइलों में सहेज लेंगे।

इसके अलावा, कंपाइलर और बिल्ड सिस्टम प्रीसेकल्ड हेडर को कैश करना चाहते हैं ताकि उन्हें एक से अधिक बार पार्स करने से बचा जा सके।


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