दिलचस्प पोस्ट
.txt फ़ाइल में लिखें? मैं एक वर्ग को 'नए' ऑपरेटर के माध्यम से आवंटित होने से कैसे रोकूं? (मैं यह सुनिश्चित करना चाहूंगा कि मेरा आरएआईआई वर्ग हमेशा स्टैक पर आवंटित होता है।) पूर्णांकों की वास्तविक संख्या को जानने के बिना कई पूर्णांक स्कैन करें प्रमाण पत्र की दुकान में एक प्रमाण पत्र में निजी कुंजी के लिए ASP.NET का उपयोग कैसे करें? एंड्रॉइड के लिए ffmpeg (ट्यूटोरियल के प्रयोग से: "ffmpeg और एंड्रॉइड। एमके") जावास्क्रिप्ट arrays primitives हैं? तार? वस्तुओं? CodeIgniter – एक दृश्य में दूसरे पृष्ठ से लिंक करने का सही तरीका आईई 6 और आईई 7 जेड-इंडेक्स प्रॉब्लम थ्रेड को दोबारा शुरू करने पर उदाहरण को पुन: निर्माण करने की आवश्यकता क्यों है? क्या इस .form.submit के लिए एक बेहतर jQuery समाधान है? प्रोटोटाइप का उपयोग करते हुए जावास्क्रिप्ट में किसी ऑब्जेक्ट की हर प्रॉपर्टी को बदलना? आप केवल Windows 'अंतर्निहित क्षमताओं का उपयोग करके स्क्रिप्ट से कैसे ज़िप या अनझिप कर सकते हैं? आवेदन पुनरारंभ होने पर पुश अधिसूचना को कैसे संभालना है? पायथन में समान सूचकांक / विशेषता द्वारा ट्यूप्ले / ऑब्जेक्ट की सूची कैसे समूहित करें? दो रास्ते / उल्टे नक्शा

आगे की घोषणा क्यों आवश्यक है?

संभव डुप्लिकेट:
सी ++ हेडर फाइलों को खत्म करना चाहिए?

सी # और जावा जैसी भाषाओं में इसका उपयोग करने से पहले एक वर्ग को घोषित करने की आवश्यकता नहीं है (उदाहरण के लिए) अगर मैं इसे सही ढंग से समझता हूं तो यह इसलिए है क्योंकि कंपाइलर कोड पर दो पास करता है। पहले में यह सिर्फ "उपलब्ध जानकारी एकत्र करता है" और दूसरे में यह जांचता है कि कोड सही है।

सी और सी ++ में कंपाइलर केवल एक ही पास करता है इसलिए सभी को उस समय उपलब्ध होना चाहिए।

तो मेरा सवाल यह है कि सी और सी ++ में ऐसा क्यों नहीं किया गया है। क्या यह हेडर फाइलों की ज़रूरतों को खत्म नहीं करेगा?

Solutions Collecting From Web of "आगे की घोषणा क्यों आवश्यक है?"

संक्षेप में उत्तर यह है कि कंप्यूटिंग पावर और संसाधनों को तेजी से विकसित किया गया था कि सी को परिभाषित किया गया था और जिस समय 25 साल बाद जावा आया था,

लंबा जवाब …

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

जब सी 1 9 72 में बनाया गया था, कंप्यूटिंग संसाधन अधिक दुर्लभ थे और एक उच्च प्रीमियम पर – एक जटिल कार्यक्रम की संपूर्ण प्रतीकात्मक तालिका को संग्रह करने के लिए आवश्यक स्मृति को एक बार बस अधिकांश प्रणालियों में उपलब्ध नहीं था। फिक्स्ड स्टोरेज भी महंगा और बहुत धीमा था, इसलिए आभासी स्मृति जैसे विचार या डिस्क पर प्रतीकात्मक तालिका के भंडारण के भाग में उचित समय सीमा में संकलन को अनुमति नहीं दी जाएगी।

इस समस्या का सबसे अच्छा समाधान यह था कि कोड को एक छोटे से टुकड़ों में विभाजित किया जा सकता था, जिसके बाद एक प्रतीक तालिका के कुछ भागों में आवश्यक होगा कि समय के पहले संकलन इकाइयां कौन सी संकलन इकाइयां होंगी। प्रोग्रामर के उपयोग के बारे में बताए गए प्रोग्रामर पर एक बहुत ही छोटा काम पर विचार करना, प्रोग्रामर द्वारा उपयोग किए जाने वाले किसी भी चीज़ के लिए कंप्यूटर को पूरे कार्यक्रम के लिए खोज करने के जबरदस्त प्रयास को बचाया जाएगा

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

लगभग 17 साल बाद बनाया गया सी ++, सी के एक सुपरसेट के रूप में परिभाषित किया गया था, और इसलिए उसी तंत्र का उपयोग करना था

1 9 5 के आसपास जावा के समय के दौरान, औसत कंप्यूटर्स में पर्याप्त मेमोरी थी जो एक प्रतीकात्मक तालिका धारण कर रही थी, यहां तक ​​कि एक जटिल परियोजना के लिए, अब कोई बड़ा बोझ नहीं था। और जावा पिछड़े-पीछे होने के लिए तैयार नहीं था- सी के साथ संगत, इसलिए उसे विरासत तंत्र को अपनाने की आवश्यकता नहीं थी। सी # समान रूप से बेमानी थी

नतीजतन, उनके डिजाइनर ने प्रोग्रामर से प्रतीकात्मक घोषणापत्र को बांटने के बोझ को बदलने और फिर कंप्यूटर पर डाल दिया, चूंकि संकलन के कुल प्रयास के अनुपात में इसकी न्यूनतम कीमत थी।

नीचे की रेखा: संकलक तकनीक में प्रगति हुई है जो आगे की घोषणाओं को अनावश्यक बनाते हैं। प्लस कंप्यूटर हजारों बार तेज होते हैं, और इससे आगे की घोषणाओं की कमी को संभालने के लिए अतिरिक्त गणना आवश्यक हो सकती है।

सी और सी + + बड़े हैं और एक समय में मानकीकृत किए गए थे जब प्रत्येक CPU चक्र को सहेजना आवश्यक था

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

बेहतर या बदतर के लिए, सी (और सी ++) के शब्दों के लिए नियम "एकल पास" शैली व्यवहार को जनादेश देते हैं। बस उदाहरण के लिए, इस तरह से कोड पर विचार करें:

int i; int f() { i = 1; int i = 2; } 

i=1 को वैश्विक रूप से नियत किया जाता है, f() अंदर परिभाषित नहीं किया गया है। इसका कारण यह है कि असाइनमेंट के समय, i की स्थानीय परिभाषा अभी तक नहीं देखी गई है, इसलिए इसे ध्यान में नहीं रखा गया है। आप इन नियमों को अभी भी एक दो-पास संकलक के साथ पालन कर सकते हैं, लेकिन ऐसा करने से गैर तुच्छ हो सकते हैं मैंने अपने चश्मे को निश्चित रूप से पता नहीं किया है, लेकिन मेरा तात्पर्य यह होगा कि जावा और सी # इस संबंध में सी और सी ++ से अलग है।

संपादित करें: चूंकि एक टिप्पणी ने कहा कि मेरा अनुमान गलत था, मैंने थोड़ी जांच की। जावा भाषा संदर्भ के अनुसार, § 14.4.2, जावा का मानना ​​है कि सी ++ (एक छोटा अलग, लेकिन पूरी तरह से बहुत कुछ नहीं)

कम से कम जैसा कि मैंने सी # भाषा विनिर्देश पढ़ा है, (चेतावनी: शब्द फ़ाइल) हालांकि, यह अलग है यह (§3.7.1) कहता है: "स्थानीय-चर-घोषणा-घोषणा (§8.5.1) में घोषित स्थानीय चर का दायरा ब्लॉक है जिसमें घोषणा की जाती है।"

ऐसा लगता है कि सी # में, स्थानीय चर पूरे ब्लॉक में दिखाई दे सकता है जिसमें यह घोषित किया जाता है, इसलिए मैंने दिया उदाहरण के समान कोड के साथ, असाइनमेंट वैश्विक चर के लिए होगा, वैश्विक नहीं होगा

तो, मेरा अनुमान आधा सही था: जावा इस प्रकार है (इस संदर्भ में सी ++ के रूप में बहुत ज्यादा वही नियम है, लेकिन सी # नहीं है

यह सी / सी ++ में छोटे संकलन मॉड्यूल के कारण है सी / सी ++ में प्रत्येक .c / .cpp फ़ाइल को अलग से संकलित किया जाता है, जिससे एक .obj मॉड्यूल बनाया जा सकता है। इस प्रकार संकलक को अन्य संकलन मॉड्यूल में घोषित प्रकारों और चर के बारे में जानकारी की आवश्यकता होती है। यह जानकारी आगे की घोषणाओं के रूप में आपूर्ति की जाती है, आमतौर पर हेडर फाइल में।

दूसरी तरफ सी #, एक ही बार में कई .सीसी फ़ाइलों को एक बड़े संकलन मॉड्यूल में संकलित करता है।

वास्तव में, जब सी # कार्यक्रम से अलग संकलित मॉड्यूल को संदर्भित करते हैं, तो संकलक को घोषणाओं (प्रकार नामों आदि) को सी ++ कंपाइलर के समान ही पता होना चाहिए। यह जानकारी संकलित मॉड्यूल से सीधे प्राप्त की जाती है। सी ++ में एक ही जानकारी को स्पष्ट रूप से अलग किया गया है (इसीलिए आप सी ++ – कंपाइल किए गए डीएलएल से वेरिएबल नाम नहीं खोज सकते हैं, लेकिन इसे नेट विधानसभा से निर्धारित कर सकते हैं)।

सी ++ में अग्रेषण घोषणाएं एक अन्य प्रकार के कोड के बारे में मेटाडेटा प्रदान करने का एक तरीका है जो वर्तमान में संकलित स्रोत द्वारा कंपाइलर के लिए इस्तेमाल किया जा सकता है, इसलिए यह सही कोड जनरेट कर सकता है।

यह मेटाडेटा लिंक्ड पुस्तकालय / घटक के लेखक से आ सकता है। हालांकि, यह स्वचालित रूप से उत्पन्न हो सकता है (उदाहरण के लिए उपकरण हैं जो COM ऑब्जेक्ट के लिए C ++ हेडर फाइल उत्पन्न करते हैं)। किसी भी स्थिति में, मेटाडेटा व्यक्त करने का सी ++ तरीका हेडर फाइलों के माध्यम से होता है, जिसे आपको अपने स्रोत कोड में शामिल करने की आवश्यकता होती है।

सी # / नेट भी संकलन समय पर समान मेटाडाटा का उपयोग करता है। हालांकि, उस मेटाडेटा को स्वचालित रूप से तब जनरेट किया जाता है जब विधानसभा इसे लागू होती है और आमतौर पर इसमें अंतर्निहित होता है। इस प्रकार, जब आप अपने सी # प्रोजेक्ट में असेंबली का संदर्भ देते हैं, तो आप अनिवार्य रूप से कम्पाइलर को "इस सम्मेलन में आपको आवश्यक मेटाडेटा के लिए भी देखें, कृपया देखें"।

दूसरे शब्दों में, सी # में मेटाडाटा पीढ़ी और खपत डेवलपर्स के लिए अधिक पारदर्शी है, जिससे उन्हें अपने मायके कोड लिखने में मदद मिलती है।

विधानसभा के साथ बंडल कोड के बारे में मेटाडाटा होने के साथ-साथ अन्य लाभ भी हैं। रिफ्लेक्शन, कोड उत्सर्जन, ऑन-द फ्लाई सीरियललाइज़ेशन – ये सभी रन-टाइम पर उचित कोड जनरेट करने में सक्षम होने के लिए मेटाडेटा पर निर्भर करते हैं।

सी ++ एनालॉग यह आरटीटीआई होगा, हालांकि यह व्यापक रूप से अपनाने नहीं है क्योंकि ओटी असंगत कार्यान्वयन।

एरिक लिपरट से, सभी चीजों का ब्लॉगर सी #: http://blogs.msdn.com/ericlippertarch//2010/02/04/how-many-passes.aspx से आंतरिक:

सी # भाषा की आवश्यकता नहीं है कि प्रयोजनों के उपयोग से पहले घोषणाएं होती हैं, जो कि उपयोगकर्ता पर और कंपाइलर लेखक पर दो प्रभाव पड़ता है। […]

संकलक लेखक पर प्रभाव यह है कि हमारे पास "दो पास" संकलक होना चाहिए। पहले पास में, हम घोषणाओं की खोज करते हैं और निकायों को नजरअंदाज करते हैं। एक बार जब हमने सी ++ में शीर्ष लेखों से प्राप्त घोषणाओं से सारी जानकारी एकत्र की है, तो हम कोड के ऊपर एक दूसरा पास लेते हैं और आईएल के लिए निकाले जाते हैं।

संक्षेप में, कुछ का उपयोग करके इसे सी # में घोषित करने की आवश्यकता नहीं है, जबकि यह सी ++ में है इसका मतलब है कि सी ++ में, आपको स्पष्ट रूप से बातें घोषित करने की आवश्यकता है, और हेडर फाइलों के साथ ऐसा करना अधिक सुविधाजनक और सुरक्षित है ताकि आप एक परिभाषा नियम का उल्लंघन न करें।