C ++ को एक अलग हेडर फ़ाइल की आवश्यकता क्यों है?


138

मैं वास्तव में कभी नहीं समझ पाया कि C ++ को .cpp फ़ाइल की तरह ही फ़ंक्शन के साथ एक अलग हेडर फ़ाइल की आवश्यकता क्यों है। यह कक्षाएं बनाना और उन्हें बहुत मुश्किल से फिर से तैयार कर रहा है, और यह प्रोजेक्ट में अनावश्यक फ़ाइलों को जोड़ता है। और फिर हेडर फ़ाइलों को शामिल करने में समस्या है, लेकिन यह स्पष्ट रूप से जांचने के लिए कि क्या यह पहले से ही शामिल है।

1998 में C ++ की पुष्टि की गई थी, इसलिए इसे इस तरह से क्यों बनाया गया है? एक अलग हेडर फ़ाइल के क्या फायदे हैं?


अनुवर्ती सवाल:

कंपाइलर को .cpp फ़ाइल को कोड के साथ कैसे पता चलता है, जब मैं सभी .h फ़ाइल को शामिल करता हूँ? क्या यह मान लेता है कि .cpp फ़ाइल का .h फ़ाइल के समान नाम है, या क्या यह वास्तव में निर्देशिका ट्री में सभी फ़ाइलों के माध्यम से दिखता है?


2
यदि आप किसी एकल फ़ाइल को केवल चेकआउट लेज़ (www.lazycplusplus.com) संपादित करना चाहते हैं।
रिचर्ड कॉर्डेन

3
सटीक डुप्लिकेट: stackoverflow.com/questions/333889 । डुप्लिकेट के पास: stackoverflow.com/questions/752793
पीटर मोर्टेंसन

जवाबों:


105

आप घोषणाओं से परिभाषाओं को अलग करने के बारे में पूछ रहे हैं, हालांकि हेडर फ़ाइलों के लिए अन्य उपयोग हैं।

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

जिन कारणों से आप अलग होना चाहते हैं , वे हैं:

  1. बिल्ड समय में सुधार करने के लिए।
  2. परिभाषाओं के स्रोत के बिना कोड के खिलाफ लिंक करने के लिए।
  3. सब कुछ "इनलाइन" चिह्नित करने से बचने के लिए।

यदि आपका अधिक सामान्य प्रश्न है, "C ++ जावा के समान क्यों नहीं है?", तो मुझे पूछना होगा, "आप जावा के बजाय C ++ क्यों लिख रहे हैं?" ;-p

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

तो #includeएक सीधा पाठ प्रतिस्थापन है। यदि आप हेडर फ़ाइलों में सब कुछ परिभाषित करते हैं, तो प्रीप्रोसेसर आपकी परियोजना में हर स्रोत फ़ाइल की एक विशाल प्रतिलिपि और पेस्ट बनाता है, और उसे कंपाइलर में फीड करता है। तथ्य यह है कि 1998 में C ++ मानक का अनुसमर्थन किया गया था, इससे कोई लेना-देना नहीं है, यह तथ्य है कि C ++ के लिए संकलन वातावरण C के बहुत निकट है।

आपके अनुवर्ती प्रश्न का उत्तर देने के लिए मेरी टिप्पणियों को परिवर्तित करना:

कंपाइलर कैसे करता है। इसमें कोड वाली .cpp फाइल को खोजें

ऐसा नहीं है, कम से कम उस समय नहीं जब यह उस कोड को संकलित करता है जो हेडर फ़ाइल का उपयोग करता है। वे फ़ंक्शन जिन्हें आप लिंक कर रहे हैं, उन्हें अभी तक लिखने की आवश्यकता नहीं है, कंपाइलर को यह जानने में कोई दिक्कत नहीं है कि .cppवे किस फ़ाइल में होंगे। सब कुछ कॉलिंग कोड को संकलन समय पर जानना आवश्यक है, फ़ंक्शन घोषणा में व्यक्त किया गया है। लिंक समय पर आप .oफ़ाइलों, या स्थिर या गतिशील पुस्तकालयों की एक सूची प्रदान करेंगे , और प्रभाव में हेडर एक वादा है कि कार्यों की परिभाषाएं कहीं न कहीं होंगी।


3
"जिन कारणों से आप अलग होना चाहते हैं, उन्हें जोड़ने के लिए:" और मैं शीर्ष लेख फ़ाइलों का सबसे महत्वपूर्ण कार्य है: कार्यान्वयन से कोड संरचना डिजाइन को अलग करना, क्योंकि: A. जब आप वास्तव में जटिल संरचनाओं में शामिल होते हैं, जिसमें कई ऑब्जेक्ट शामिल होते हैं हेडर फ़ाइलों के माध्यम से झारना और याद रखना आसान है कि वे कैसे एक साथ काम करते हैं, आपके हेडर टिप्पणियों द्वारा पूरक हैं। B। एक व्यक्ति सभी वस्तु संरचना को परिभाषित करने के लिए संयुक्त राष्ट्र का ध्यान रखता है और कुछ अन्य कार्यान्वयन का ध्यान रख रहे हैं, यह चीजों को व्यवस्थित रखता है। मुझे लगता है कि यह जटिल कोड को अधिक पठनीय बनाता है।
एंड्रेस कैनेला जूल

सबसे सरल तरीके से मैं हेडर बनाम सीपीपी फ़ाइलों की उपयोगिता के बारे में सोच सकता हूं अलग-अलग इंटरफ़ेस बनाम कार्यान्वयन को अलग करना है जो वास्तव में मध्यम / बड़ी परियोजनाओं के लिए मदद करता है।
कृष्णा ओझा

मेरा इरादा था कि (2) में शामिल किया जाए, "परिभाषा के बिना कोड के खिलाफ लिंक"। ठीक है, इसलिए आपके पास अभी भी परिभाषाओं के साथ गिट रेपो तक पहुंच हो सकती है, लेकिन मुद्दा यह है कि आप अपने कोड को उसकी निर्भरता के कार्यान्वयन से अलग कर सकते हैं और फिर लिंक कर सकते हैं। अगर शाब्दिक रूप से आप सभी चाहते थे कि अलग-अलग फ़ाइलों में इंटरफ़ेस / कार्यान्वयन अलग-अलग हो, तो अलग से निर्माण के लिए कोई चिंता नहीं है, तो आप ऐसा कर सकते हैं कि केवल foo_interface.h होने से foo_implementation.h शामिल हैं।
स्टीव जेसप

4
@AndresCanella नहीं यह नहीं है। यह पढ़ने और अपने खुद के कोड को एक बुरा सपना बनाए रखता है। पूरी तरह से समझने के लिए कि कोड में क्या कुछ है जो आपको n फ़ाइलों के बजाय 2n फ़ाइलों के माध्यम से कूदने की आवश्यकता है। यह सिर्फ बिग-ओह नोटेशन नहीं है, 2 एन सिर्फ एन की तुलना में बहुत अंतर करता है।
बलोएज माइकालिक

1
मैं दूसरा कि इसका झूठ जो हेडर की मदद करता है। उदाहरण के लिए मिनिक्स स्रोत की जांच करें, यह पालन करना बहुत मुश्किल है कि यह कहां से शुरू होता है जहां नियंत्रण पारित किया जाता है, जहां चीजें घोषित / परिभाषित होती हैं .. अगर इसे अलग गतिशील मॉड्यूल के माध्यम से बनाया गया था, तो यह एक चीज की समझ में आने के बाद पच जाएगा एक निर्भरता मॉड्यूल। इसके बजाय, आपको शीर्ष लेखों का पालन करने की आवश्यकता है और यह इस तरह से लिखे गए किसी भी कोड को नरक में पढ़ता है। इसके विपरीत, नोडज यह स्पष्ट करता है कि बिना किसी इफेड के क्या आता है, और आप आसानी से पहचान सकते हैं कि कहां से आया है।
दिमित्री

91

C ++ ऐसा इसलिए करता है क्योंकि C ने ऐसा किया था, इसलिए असली सवाल यह है कि C ने ऐसा क्यों किया? विकिपीडिया इस पर थोड़ी बात करता है।

नई संकलित भाषाएँ (जैसे जावा, C #) आगे की घोषणाओं का उपयोग नहीं करती हैं; पहचानकर्ता स्वचालित रूप से स्रोत फ़ाइलों से पहचाने जाते हैं और गतिशील लाइब्रेरी प्रतीकों से सीधे पढ़े जाते हैं। इसका मतलब है कि शीर्ष लेख फ़ाइलों की आवश्यकता नहीं है।


13
+1 सिर पर कील ठोकता है। यह वास्तव में एक क्रिया स्पष्टीकरण की आवश्यकता नहीं है।
MSalters

6
इसने मेरे नाखून को सिर पर नहीं मारा :( मुझे अभी भी देखना है कि C ++ को आगे की घोषणाओं का उपयोग क्यों करना है और यह स्रोत फ़ाइलों से पहचानकर्ताओं को क्यों नहीं पहचान सकता है और डायनेमिक लाइब्रेरी प्रतीकों से सीधे पढ़ सकता है, और C ++ ने ऐसा क्यों किया रास्ता सिर्फ इसलिए कि C ने इसे इस तरह किया: p
अलेक्जेंडर टेलर

3
और आप @AlexanderTaylor किए जाने के लिए एक बेहतर प्रोग्रामर हैं :)
डोनाल्ड बायर्ड

66

कुछ लोग हेडर फ़ाइलों को एक लाभ मानते हैं:

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

अंततः, हेडर सिस्टम 70 के दशक से एक विरूपण साक्ष्य है जब सी डिजाइन किया गया था। इसके बाद, कंप्यूटर में बहुत कम मेमोरी थी, और पूरे मॉड्यूल को मेमोरी में रखना सिर्फ एक विकल्प नहीं था। एक कंपाइलर को शीर्ष पर फ़ाइल पढ़ना शुरू करना था, और फिर स्रोत कोड के माध्यम से रैखिक रूप से आगे बढ़ना चाहिए। शीर्ष लेख तंत्र इसे सक्षम करता है। संकलक को अन्य अनुवाद इकाइयों पर विचार करने की आवश्यकता नहीं है, इसे बस ऊपर से नीचे तक कोड को पढ़ना होगा।

और C ++ ने इस सिस्टम को पीछे की संगतता के लिए बनाए रखा।

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

हालाँकि, C ++ 0x के प्रस्तावों में से एक उचित मॉड्यूल सिस्टम को जोड़ना था, जिससे कोड को .NET या Java के समान संकलित किया जा सके, सभी बड़े मॉड्यूल में, एक बार में और बिना हेडर के। इस प्रस्ताव ने C ++ 0x में कटौती नहीं की, लेकिन मेरा मानना ​​है कि यह "हम बाद में ऐसा करना पसंद करेंगे" श्रेणी में है। शायद टीआर 2 या इसी तरह के।


यह पृष्ठ पर सबसे अच्छा जवाब है। धन्यवाद!
चक ले बट

29

मेरी (सीमित - मैं सामान्य रूप से सी डेवलपर नहीं हूं) समझ के अनुसार, यह सी में निहित है। याद रखें कि सी को यह नहीं पता है कि वर्ग या नाम स्थान क्या हैं, यह सिर्फ एक लंबा कार्यक्रम है। इसके अलावा, कार्यों का उपयोग करने से पहले उन्हें घोषित किया जाना चाहिए।

उदाहरण के लिए, निम्नलिखित को एक संकलक त्रुटि देनी चाहिए:

void SomeFunction() {
    SomeOtherFunction();
}

void SomeOtherFunction() {
    printf("What?");
}

त्रुटि यह होनी चाहिए कि "SomeOtherFunction घोषित नहीं है" क्योंकि आप इसे घोषणा से पहले कहते हैं। इसे ठीक करने का एक तरीका है, SomeFtherFunction को SomeFunction से ऊपर ले जाना। एक और तरीका यह है कि पहले कार्य हस्ताक्षर घोषित किया जाए:

void SomeOtherFunction();

void SomeFunction() {
    SomeOtherFunction();
}

void SomeOtherFunction() {
    printf("What?");
}

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

अब, कल्पना कीजिए कि आपके पास कुछ अलग .c फ़ाइलों में SomeFunction और SomeOtherFunction हैं। फिर आपको Some.c में "SomeOther.c" #include करना होगा। अब, SomeOther.c पर कुछ "निजी" फ़ंक्शन जोड़ें। चूंकि C निजी कार्यों को नहीं जानता है, इसलिए यह फ़ंक्शन Some.c में भी उपलब्ध होगा।

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

तो मुख्य कारण वास्तव में सुविधा के लिए है, स्रोत कोड संरक्षण के लिए और आपके आवेदन के कुछ हिस्सों के बीच डिकम्प्लिंग का एक सा है।

हालांकि वह सी था। C ++ ने कक्षाएं और निजी / सार्वजनिक संशोधक पेश किए, इसलिए यदि आप अभी भी पूछ सकते हैं कि क्या वे आवश्यक हैं, तो C ++ AFAIK को अभी भी उपयोग करने से पहले कार्यों की घोषणा की आवश्यकता है। इसके अलावा, कई सी ++ डेवलपर्स हैं या सी डेवेलोपर्स भी थे और अपनी अवधारणाओं और आदतों को सी ++ में ले लिया - क्यों नहीं तोड़ा गया है?


5
संकलक कोड के माध्यम से क्यों नहीं चल सकता है और सभी फ़ंक्शन परिभाषाएं ढूंढ सकता है? ऐसा लगता है कि संकलक में प्रोग्राम करना बहुत आसान होगा।
Marius

3
यदि आपके पास स्रोत है, जो आपके पास अक्सर नहीं है। संकलित C ++ कोड को लोड करने और लिंक करने के लिए केवल पर्याप्त अतिरिक्त जानकारी के साथ प्रभावी रूप से मशीन कोड है। फिर, आप प्रवेश बिंदु पर सीपीयू को इंगित करते हैं, और इसे चलने देते हैं। यह जावा या सी # से मौलिक रूप से अलग है, जहां कोड को एक मध्यवर्ती बायटेकोड में संकलित किया जाता है, जिसमें इसकी सामग्री पर मेटाडेटा होता है।
DevSolar

मैं अनुमान लगा रहा हूं कि 1972 में, यह कंपाइलर के लिए एक महंगा ऑपरेशन हो सकता था।
माइकल Stum

बिल्कुल माइकल स्टम ने क्या कहा। जब इस व्यवहार को परिभाषित किया गया था, एक एकल अनुवाद इकाई के माध्यम से एक रैखिक स्कैन केवल एक चीज थी जिसे व्यावहारिक रूप से लागू किया जा सकता था।
जलफ

3
यूप - टेप मास टेजर के साथ एक 16 कड़वे पर संकलन गैर-तुच्छ है।
मसलक

11

पहला फायदा: यदि आपके पास हेडर फाइलें नहीं हैं, तो आपको स्रोत फ़ाइलों को अन्य स्रोत फ़ाइलों में शामिल करना होगा। यह शामिल फ़ाइलों को फिर से संकलित करने का कारण होगा जब शामिल फ़ाइल में परिवर्तन होता है।

दूसरा लाभ: यह विभिन्न इकाइयों (विभिन्न डेवलपर्स, टीमों, कंपनियों आदि) के बीच कोड को साझा किए बिना इंटरफेस साझा करने की अनुमति देता है।)


1
क्या आप इसका अर्थ लगा रहे हैं, जैसे C # 'में आपको स्रोत फ़ाइलों को अन्य स्रोत फ़ाइलों में शामिल करना होगा'? क्योंकि जाहिर है आप नहीं दूसरे फ़ायदे के लिए, मुझे लगता है कि यह बहुत अधिक भाषा पर निर्भर है: आप .h फ़ाइलों का उपयोग नहीं करेंगे, जैसे डेल्फी
व्लागेड

आपको पूरे प्रोजेक्ट को किसी भी तरह से फिर से तैयार करना है, इसलिए पहला फायदा क्या है?
Marius

ठीक है, लेकिन मुझे नहीं लगता कि एक भाषा की सुविधा है। परिभाषा "समस्या" से पहले सी घोषणा से निपटने के लिए यह अधिक व्यावहारिक है। यह किसी प्रसिद्ध कहावत की तरह है "यह एक बग नहीं है जो एक विशेषता है" :)
न्यूरो

@ मार्स: हाँ, यह वास्तव में मायने रखता है। पूरे प्रोजेक्ट को जोड़ना पूरे प्रोजेक्ट को संकलित और लिंक करने से अलग है। जैसे ही प्रोजेक्ट में फ़ाइलों की # वृद्धि होती है, उन सभी का संकलन वास्तव में कष्टप्रद हो जाता है। @ उन्नत: आप सही हैं, लेकिन मैंने दूसरी भाषा के साथ c ++ की तुलना नहीं की है। मैंने केवल स्रोत फ़ाइलों का उपयोग करके स्रोत और हेडर फ़ाइलों का उपयोग करके तुलना की।
एरियल

C # दूसरों में स्रोत फ़ाइलों को शामिल नहीं करता है, लेकिन आपको अभी भी मॉड्यूल को संदर्भित करना होगा - और यह कि कंपाइलर आपके कोड का उपयोग करने वाले प्रतीकों को पार्स करने के लिए स्रोत फ़ाइलों (या बाइनरी में प्रतिबिंबित) को लाता है।
gbjbaanb

5

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

इस सीमा की क्षतिपूर्ति करने के लिए, C और C ++ घोषणाओं की अनुमति देते हैं और इन घोषणाओं को उन मॉड्यूल में शामिल किया जा सकता है जो प्रीप्रोसेसर के #include निर्देश की मदद से उनका उपयोग करते हैं।

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

बाध्यकारी जानकारी को संकलक आउटपुट में शामिल नहीं किए जाने का कारण सरल है: इसे रनटाइम (किसी भी प्रकार की जाँच संकलन समय पर होती है) की आवश्यकता नहीं है। यह सिर्फ जगह बर्बाद करेगा। याद रखें कि C / C ++ एक ऐसे समय से आता है जहां एक निष्पादन योग्य या लाइब्रेरी का आकार काफी मायने रखता था।


मैं आपसे सहमत हुँ। मुझे यहाँ समान विचार मिला: stackoverflow.com/questions/3702132/…
smwikipedia

4

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

हां, इस बिंदु पर (पहले सी ++ मानक के 10 साल बाद और इसके उपयोग में गंभीरता से बढ़ने के 20 साल बाद) यह पूछना आसान है कि इसमें उचित मॉड्यूल प्रणाली क्यों नहीं है। जाहिर है कि आज डिज़ाइन की जा रही कोई भी नई भाषा C ++ की तरह काम नहीं करेगी। लेकिन वह C ++ की बात नहीं है।

C ++ का बिंदु विकासवादी होना है, मौजूदा अभ्यास का एक सहज निरंतरता है, केवल नई क्षमताओं को जोड़ना (बिना अक्सर) उन चीजों को तोड़ना जो अपने उपयोगकर्ता समुदाय के लिए पर्याप्त रूप से काम करते हैं।

इसका मतलब यह है कि यह कुछ चीजों को कठिन बनाता है (विशेषकर नए प्रोजेक्ट को शुरू करने वाले लोगों के लिए), और कुछ चीजें आसान (विशेष रूप से मौजूदा कोड को बनाए रखने वालों के लिए) अन्य भाषाओं की तुलना में।

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


आप C # और C ++ को कैसे एकीकृत करते हैं? COM के माध्यम से?
पीटर मोर्टेंसन

1
तीन मुख्य तरीके हैं, "सबसे अच्छा" आपके मौजूदा कोड पर निर्भर करता है। मैंने तीनों का इस्तेमाल किया है। मैं जिसका सबसे अधिक उपयोग करता हूं वह COM है क्योंकि मेरा मौजूदा कोड पहले से ही इसके चारों ओर डिज़ाइन किया गया था, इसलिए यह व्यावहारिक रूप से सहज है, मेरे लिए बहुत अच्छा काम करता है। कुछ विषम स्थानों में मैं C ++ / CLI का उपयोग करता हूं जो किसी भी स्थिति के लिए अविश्वसनीय रूप से चिकनी एकीकरण देता है जहां आपके पास पहले से COM इंटरफेस नहीं है (और आप मौजूदा COM इंटरफेस का उपयोग करना पसंद कर सकते हैं, भले ही आपके पास हो)। अंत में p / invoke है जो मूल रूप से आपको DLL से उजागर किसी भी C- जैसे फ़ंक्शन को कॉल करने देता है, जिससे आप सीधे C # से किसी भी Win32 API को कॉल कर सकते हैं।
डैनियल इयरविकर

4

ठीक है, 1998 में C ++ की पुष्टि की गई थी, लेकिन यह इससे बहुत लंबे समय तक उपयोग में रहा था, और अनुसमर्थन मुख्य रूप से संरचना को लागू करने के बजाय वर्तमान उपयोग को कम कर रहा था। और चूंकि C ++ C पर आधारित था, और C के पास हेडर फाइलें हैं, C ++ उनके पास भी है।

हेडर फ़ाइलों का मुख्य कारण फ़ाइलों के अलग संकलन को सक्षम करना और निर्भरता कम करना है।

मान लें कि मेरे पास foo.cpp है, और मैं bar.h / bar.cpp फ़ाइलों के कोड का उपयोग करना चाहता हूं।

मैं foo.cpp में "bar.h" #include कर सकता हूं, और तब प्रोग्राम और संकलन foo.cpp कर सकता हूं, भले ही bar.cpp मौजूद न हो। हेडर फ़ाइल कंपाइलर के लिए एक वादे के रूप में कार्य करता है कि बार / h में कक्षाएं / फ़ंक्शन रन-टाइम पर मौजूद होंगे, और इसमें वह सब कुछ है जो पहले से ही जानना आवश्यक है।

बेशक, अगर बार में कार्य नहीं होते हैं, तो जब मैं अपने प्रोग्राम को लिंक करने की कोशिश करता हूं, तो यह लिंक नहीं होगा और मुझे एक त्रुटि मिलेगी।

एक साइड-इफेक्ट यह है कि आप अपने सोर्स कोड को प्रकट किए बिना उपयोगकर्ताओं को एक हेडर फाइल दे सकते हैं।

एक और यह है कि यदि आप अपने .cpp फ़ाइल में अपने कोड के कार्यान्वयन को बदलते हैं, लेकिन हैडर को बिल्कुल भी नहीं बदलते हैं, तो आपको केवल उन सभी चीज़ों के बजाय * .cpp फ़ाइल को संकलित करने की आवश्यकता है जो इसका उपयोग करते हैं। बेशक, यदि आप हेडर फ़ाइल में बहुत अधिक कार्यान्वयन करते हैं, तो यह कम उपयोगी हो जाता है।


3

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

यह वास्तव में एक गुंजाइश समस्या है।


1

1998 में C ++ की पुष्टि की गई थी, इसलिए इसे इस तरह से क्यों बनाया गया है? एक अलग हेडर फ़ाइल के क्या फायदे हैं?

वास्तव में पहली बार प्रोग्रामों की जांच करते समय, हेडर फाइलें बहुत उपयोगी हो जाती हैं, हेडर फाइलों की जांच (केवल एक टेक्स्ट एडिटर का उपयोग करके) आपको अन्य भाषाओं के विपरीत, जहां आप कक्षाओं को देखने के लिए परिष्कृत उपकरणों का उपयोग करना चाहते हैं, के विपरीत कार्यक्रम की वास्तुकला का अवलोकन करते हैं। उनके सदस्य कार्य।


1

मुझे लगता है कि असली (ऐतिहासिक) हेडर फाइल के पीछे कारण संकलक डेवलपर्स के लिए आसान की तरह बना रहा था ... लेकिन फिर, हेडर फाइल करते फायदे दे। अधिक चर्चा के लिए इस पिछले पोस्ट की
जाँच करें ...


1

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

#ifndef MY_HEADER_SWEET_GUARDIAN
#define MY_HEADER_SWEET_GUARDIAN

// [...]
// my header
// [...]

#endif // MY_HEADER_SWEET_GUARDIAN

यह वास्तव में एक भाषा की विशेषता नहीं है, बल्कि कई समावेश से निपटने का एक व्यावहारिक तरीका है।

इसलिए, मुझे लगता है कि जब सी बनाया गया था, तो आगे की घोषणा के साथ समस्याओं को कम करके आंका गया था और अब सी ++ जैसी उच्च स्तरीय भाषा का उपयोग करते हुए हमें इस तरह की चीजों से निपटना होगा।

हमारे लिए एक और बोझ गरीब C ++ उपयोगकर्ता ...


1

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

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