हमें .h को शामिल करने की आवश्यकता क्यों है जबकि सब कुछ काम करता है जब केवल .cpp फ़ाइल शामिल होती है।


18

क्यों हम दोनों को शामिल करने की जरूरत है .hऔर .cppफ़ाइलों जब तक हम शामिल करके यह पूरी तरह से काम कर सकते हैं .cppफ़ाइल?

उदाहरण के लिए: एक file.hयुक्त घोषणाएँ बनाना, फिर एक file.cppपरिभाषाएँ बनाना और दोनों में शामिल करना main.cpp

वैकल्पिक रूप से: file.cppइसमें सहित एक घोषित घोषणा / परिभाषा (कोई प्रोटोटाइप नहीं) बनाना main.cpp

दोनों मेरे लिए काम करते हैं। मैं अंतर नहीं देख सकता। शायद संकलन और लिंकिंग प्रक्रिया में कुछ अंतर्दृष्टि मदद कर सकती है।


अपने शोध को साझा करना हर किसी की मदद करता है । हमें बताएं कि आपने क्या प्रयास किया है और यह आपकी आवश्यकताओं को पूरा क्यों नहीं करता है। यह दर्शाता है कि आपने खुद को मदद करने का प्रयास करने के लिए समय लिया है, यह हमें स्पष्ट उत्तरों को दोहराने से बचाता है, और सबसे अधिक यह आपको अधिक विशिष्ट और प्रासंगिक उत्तर प्राप्त करने में मदद करता है। यह भी देखें कि कैसे पूछें
gnat

मैं पक्ष में संबंधित प्रश्नों को यहां देखने की सलाह देता हूं। programmers.stackexchange.com/questions/56215/… और programmers.stackexchange.com/questions/115368/… अच्छे पढ़े हुए हैं

यह प्रोग्रामर पर क्यों है, और एसओ पर क्यों नहीं?
मोनिका

@LightnessRacesInOrbit क्योंकि यह कोडिंग शैली का प्रश्न है और "कैसे" प्रश्न नहीं है।
CashCow

@CashCow: आप गलत एसओ की तरह लगता है, जो है नहीं एक "कैसे" साइट। यह भी लगता है कि आप इस प्रश्न को गलत समझते हैं, जो कोडिंग शैली का सवाल नहीं है।
मोनिका

जवाबों:


29

जबकि आप बताए अनुसार फाइलों को शामिल कर सकते हैं .cpp, यह एक बुरा विचार है।

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

क्या होना चाहिए प्रत्येक .cppफ़ाइल में कार्यक्रम के सबसेट के लिए परिभाषाएं शामिल हैं, जैसे कि एक वर्ग, तार्किक रूप से संगठित कार्य समूह, वैश्विक स्थैतिक चर (यदि सभी पर संयम से उपयोग करें), आदि।

प्रत्येक संकलन इकाई ( .cppफ़ाइल) में तब जो भी घोषणाएँ होती हैं, उसमें शामिल परिभाषाओं को संकलित करना आवश्यक होता है। यह फ़ंक्शंस का ट्रैक रखता है और इसे संदर्भित करता है लेकिन इसमें सम्‍मिलित नहीं है, इसलिए लिंकर उन्हें बाद में हल कर सकता है जब वह ऑब्जेक्ट कोड को एक निष्पादन योग्य या लाइब्रेरी में जोड़ता है।

उदाहरण

  • Foo.h -> कक्षा फू के लिए घोषणा (इंटरफ़ेस) शामिल है।
  • Foo.cpp -> कक्षा फू के लिए परिभाषा (कार्यान्वयन) शामिल है।
  • Main.cpp-> मुख्य विधि, कार्यक्रम प्रविष्टि बिंदु शामिल हैं। यह कोड एक फू को तत्काल बदल देता है और इसका उपयोग करता है।

दोनों Foo.cppऔर Main.cppशामिल करने की आवश्यकता है Foo.hFoo.cppइसकी आवश्यकता है क्योंकि यह उस कोड को परिभाषित कर रहा है जो वर्ग इंटरफ़ेस का समर्थन करता है, इसलिए यह जानना आवश्यक है कि वह इंटरफ़ेस क्या है। Main.cppइसकी आवश्यकता है क्योंकि यह एक फू बना रहा है और इसके व्यवहार का आह्वान कर रहा है, इसलिए यह जानना होगा कि वह व्यवहार क्या है, स्मृति में एक फू का आकार और इसके कार्यों को कैसे खोजना है, आदि लेकिन इसे अभी वास्तविक कार्यान्वयन की आवश्यकता नहीं है।

संकलक उत्पन्न होगा Foo.oसे Foo.cppजो संकलित रूप में फू वर्ग कोड के सभी शामिल हैं। यह भी उत्पन्न करता है Main.oजिसमें मुख्य विधि और वर्ग फू के अनसुलझे संदर्भ शामिल हैं।

अब लिंकर आता है, जो दो ऑब्जेक्ट फ़ाइलों को जोड़ती है Foo.oऔर Main.oएक निष्पादन योग्य फ़ाइल में। यह अनसुलझे फू संदर्भों को Main.oदेखता है लेकिन देखता है कि Foo.oइसमें आवश्यक प्रतीक हैं, इसलिए यह बोलने के लिए "बिंदुओं को जोड़ता है"। एक फ़ंक्शन कॉल Main.oअब संकलित कोड के वास्तविक स्थान से जुड़ा हुआ है, इसलिए रनटाइम पर, प्रोग्राम सही स्थान पर जा सकता है।

यदि आपने Foo.cppफ़ाइल को इसमें शामिल किया है Main.cpp, तो कक्षा फू की दो परिभाषाएं होंगी । लिंकर इसे देखेगा और कहेगा "मुझे नहीं पता कि कौन सा चुनना है, इसलिए यह एक त्रुटि है।" संकलन कदम सफल होगा, लेकिन लिंकिंग नहीं होगा। (जब तक आप सिर्फ संकलन नहीं करते हैं Foo.cppलेकिन तब यह एक अलग .cppफाइल में क्यों है ?)

अंत में, विभिन्न फ़ाइल प्रकारों का विचार C / C ++ कंपाइलर के लिए अप्रासंगिक है। यह "पाठ फ़ाइलों" को संकलित करता है जिसमें उम्मीद है कि वांछित भाषा के लिए मान्य कोड है। कभी-कभी यह फ़ाइल एक्सटेंशन के आधार पर भाषा बताने में सक्षम हो सकता है। उदाहरण के लिए, .cसंकलक विकल्पों के साथ एक फ़ाइल संकलित करें और यह C मान लेगा, जबकि एक .ccया .cppएक्सटेंशन इसे C ++ मानने के लिए कहेगा। हालाँकि, मैं आसानी से एक संकलक को C ++ के रूप में .hया यहां तक ​​कि .docxफ़ाइल संकलित करने के लिए कह सकता हूं , और यह एक वस्तु ( .o) फ़ाइल को खाली कर देगा यदि इसमें सादे पाठ प्रारूप में मान्य C ++ कोड शामिल है। ये एक्सटेंशन प्रोग्रामर के लाभ के लिए अधिक हैं। यदि मैं देखता हूं Foo.hऔर Foo.cpp, मैं तुरंत मान लेता हूं कि पहले में कक्षा की घोषणा है और दूसरी में परिभाषा है।


मुझे समझ नहीं आ रहा है कि आप यहाँ क्या तर्क दे रहे हैं। तुम सिर्फ शामिल करते हैं तो Foo.cppमें Main.cppआप शामिल करने की जरूरत नहीं .hफ़ाइल, आप एक कम फ़ाइल है, तो आप अभी भी पठनीयता के लिए अलग-अलग फ़ाइलों में विभाजित कोड पर जीत है, और अपने संकलन आदेश सरल है। जब मैं हेडर फ़ाइलों के महत्व को समझता हूं तो मुझे नहीं लगता कि यह है
बेंजामिन ग्रुएनबाम

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

2
If you had included the Foo.cpp file in Main.cpp, there would be two definitions of class Foo.प्रश्न के संबंध में सबसे महत्वपूर्ण वाक्य।
22:14

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

C / C ++ कंपाइलर / लिंकर के लिए स्रोत व्यवस्थित करने के कई तरीके हैं। पूछने वाला प्रक्रिया का अनिश्चित था, इसलिए मैंने सबसे अच्छा अभ्यास समझाया कि कोड को कैसे व्यवस्थित किया जाए और प्रक्रिया कैसे काम करती है। आप बालों को अलग-अलग तरीके से कोड को व्यवस्थित करने के लिए संभव होने के बारे में बता सकते हैं, लेकिन तथ्य यह है, मैंने समझाया कि कैसे 99% परियोजनाएं वहाँ करती हैं जो एक कारण के लिए सबसे अच्छा अभ्यास है। यह अच्छा काम करता है, और आपकी पवित्रता को बनाए रखता है।

9

सी और सी ++ प्रीप्रोसेसर की भूमिका पर अधिक पढ़ें , जो कि वैचारिक रूप से सी या सी ++ कंपाइलर का पहला "चरण" है (ऐतिहासिक रूप से यह एक अलग कार्यक्रम था /lib/cpp; अब, प्रदर्शन कारणों से यह कंपाइलर उचित cc1 या अंदर एकीकृत है cc1plus)। विशेष रूप से जीएनयू cppप्रीप्रोसेसर का प्रलेखन पढ़ें । तो संकलक व्यवहार में पहले अपनी संकलन इकाई (या अनुवाद इकाई ) को पहले से तैयार करता है और फिर प्रीप्रोसेस किए गए फॉर्म पर काम करता है।

संभवतः आपको हेडर फ़ाइल को हमेशा इसमें शामिल करना होगा, file.hयदि इसमें सम्‍मिलित है (जैसा कि परंपराओं और आदतों द्वारा निर्धारित ):

  • स्थूल परिभाषाएँ
  • प्रकार परिभाषाओं (जैसे typedef, struct, classआदि, ...)
  • static inlineकार्यों की परिभाषाएँ
  • बाहरी कार्यों की घोषणा।

ध्यान दें कि इन्हें हेडर फ़ाइल में रखना सम्मेलनों (और सुविधा) की बात है।

बेशक, आपके कार्यान्वयन file.cppको उपरोक्त सभी की आवश्यकता है, इसलिए #include "file.h" पहली बार में चाहता है ।

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

मुद्दा यह है कि प्रीप्रोसेसर केवल पाठ संचालन कर रहा है । आप (सिद्धांत रूप में) इसे कॉपी और पेस्ट से पूरी तरह से बचा सकते हैं, या इसे दूसरे "प्रीप्रोसेसर" या सी कोड जनरेटर (जैसे जीपीपी या एम 4 ) से बदल सकते हैं।

एक अतिरिक्त मुद्दा यह है कि हाल ही में C (या C ++) मानक कई मानक हेडर को परिभाषित करते हैं। अधिकांश कार्यान्वयन वास्तव में इन मानक शीर्षकों को (कार्यान्वयन विशिष्ट) फ़ाइलों के रूप में कार्यान्वित करते हैं , लेकिन मेरा मानना ​​है कि मानक कार्यान्वयन को लागू करना संभव होगा (जैसे #include <stdio.h>सी के लिए, या #include <vector>सी ++ के लिए) कुछ मैजिक ट्रिक (जैसे कुछ डेटाबेस या कुछ का उपयोग करके) संकलक के अंदर जानकारी )।

यदि जीसीसी संकलक (जैसे gccया g++) का उपयोग करते हुए आप -Hप्रत्येक समावेश के बारे में सूचित करने के लिए झंडे का उपयोग कर सकते हैं , और -C -Eझंडे प्रीप्रोसेड फॉर्म प्राप्त करने के लिए। बेशक कई अन्य संकलक झंडे हैं जो प्रीप्रोसेसिंग को प्रभावित करते हैं (जैसे शामिल फ़ाइलों को खोजने के -I /some/dir/लिए जोड़ना /some/dir/, और -Dकुछ प्रीप्रोसेसर मैक्रो, आदि को पूर्वनिर्धारित करना ....)।

एनबी। सी ++ के भविष्य के संस्करणों (शायद सी ++ 20 , शायद बाद में भी) में सी ++ मॉड्यूल हो सकते हैं ।


1
यदि लिंक सड़ते हैं, तो क्या यह अभी भी एक अच्छा जवाब होगा?
डैन पिचेलमैन

4
मैंने इसे सुधारने के लिए अपना उत्तर संपादित किया, और मैं ध्यान से लिंक-विकिपीडिया या जीएनयू डॉक्यूमेंटेशन को चुनता हूं- जो मुझे विश्वास है कि लंबे समय तक प्रासंगिक रहेगा।
बेसिल स्टारीनेविच

3

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

इससे C ++ हैडर मुहावरा पैदा होता है। यह एक कारण के लिए सम्मेलन है।

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


0

हमें चयनित शीर्षक से हेडर फ़ाइल लिखने की आवश्यकता क्यों है? एक उचित व्याख्या है, लेकिन मैं अतिरिक्त विस्तार जोड़ना चाहता था।

ऐसा लगता है कि हेडर फ़ाइलों के लिए तर्कसंगत शिक्षण और सी / सी ++ पर चर्चा करने में खो जाता है।

हेडर फ़ाइल दो अनुप्रयोग विकास समस्याओं का समाधान प्रदान करती है:

  1. इंटरफ़ेस और कार्यान्वयन का पृथक्करण
  2. बड़े कार्यक्रमों के लिए बेहतर संकलन / लिंक समय

C / C ++ छोटे प्रोग्राम से लेकर बहुत बड़ी मल्टी-मिलियन लाइन, मल्टी-हज़ार फ़ाइल प्रोग्राम तक हो सकता है। अनुप्रयोग विकास एक डेवलपर की टीमों से लेकर सैकड़ों डेवलपर्स तक हो सकता है।

आप एक डेवलपर के रूप में कई टोपी पहन सकते हैं। विशेष रूप से, आप फ़ंक्शन और कक्षाओं के लिए इंटरफ़ेस के उपयोगकर्ता हो सकते हैं, या आप फ़ंक्शन और कक्षाओं के इंटरफ़ेस के लेखक हो सकते हैं।

जब आप एक फ़ंक्शन का उपयोग कर रहे हैं, तो आपको फ़ंक्शन इंटरफ़ेस को जानने की आवश्यकता है, क्या पैरामीटर का उपयोग करना है, फ़ंक्शन क्या देता है और आपको यह जानने की आवश्यकता है कि फ़ंक्शन क्या करता है। यह हेडर फ़ाइल में आसानी से प्रलेखित है जिसे कभी भी कार्यान्वयन को देखे बिना। के कार्यान्वयन को आपने कब पढ़ा है printf? खरीदें हम हर दिन इसका इस्तेमाल करते हैं।

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

बड़े पैमाने पर विकास के लिए, संकलन और लिंकिंग में लंबा समय लग सकता है। कई मिनटों से कई घंटों तक (यहां तक ​​कि कई दिनों तक!)। सॉफ्टवेयर को इंटरफेस (हेडर) और इम्प्लीमेंटेशन (सोर्स) में विभाजित करना केवल कंपाइलिंग फाइल के लिए एक विधि प्रदान करता है, जिसे सब कुछ फिर से बनाने के बजाय संकलित करने की आवश्यकता होती है।

इसके अतिरिक्त, हेडर फाइलें डेवलपर को लाइब्रेरी (पहले से संकलित) और साथ ही हेडर फाइल प्रदान करने की अनुमति देती हैं। लाइब्रेरी के अन्य उपयोगकर्ता कभी भी कार्यान्वयन को उचित नहीं देख सकते हैं, लेकिन फिर भी हेडर फ़ाइल के साथ लाइब्रेरी का उपयोग कर सकते हैं। आप इसे C / C ++ मानक पुस्तकालय के साथ हर दिन करते हैं।

यहां तक ​​कि अगर आप एक छोटा अनुप्रयोग विकसित कर रहे हैं, तो बड़े पैमाने पर सॉफ़्टवेयर डेवलपमेंट तकनीकों का उपयोग करना एक अच्छी आदत है। लेकिन हमें यह भी याद रखना चाहिए कि हम इन आदतों का उपयोग क्यों करते हैं।


0

आप यह भी पूछ सकते हैं कि क्यों न केवल अपना सारा कोड एक फ़ाइल में रखा जाए।

सबसे सरल उत्तर कोड रखरखाव है।

ऐसे समय होते हैं जब कक्षा बनाना उचित होता है:

  • एक हेडर के भीतर सभी इनलाइन
  • एक संकलन इकाई के भीतर सभी और कोई हेडर बिल्कुल नहीं।

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

(टेम्प्लेट, जिसे सभी इनबिल्ड करने की आवश्यकता है, थोड़ा अलग मुद्दा है)।

हेडर के भीतर एक क्लास बनाने का अन्य समय वह है जब आप कई प्रोजेक्ट्स में क्लास का उपयोग कर सकते हैं और विशेष रूप से पुस्तकालयों में लिंक करने से बचना चाहते हैं।

एक समय जब आप एक संपूर्ण इकाई को एक संकलन इकाई के भीतर शामिल कर सकते हैं और इसके शीर्षलेख को बिल्कुल उजागर नहीं कर सकते हैं:

  • एक "इम्प्लांट" वर्ग जो केवल उस वर्ग द्वारा उपयोग किया जाता है जिसे वह लागू करता है। यह उस वर्ग का कार्यान्वयन विवरण है, और बाहरी रूप से इसका उपयोग नहीं किया जाता है।

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

  • एक "फ़नकार" टाइप क्लास।

दूसरे शब्दों में, जहाँ आप नहीं चाहते कि कोई भी हेडर शामिल करें।

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

हालाँकि "रख-रखाव" केवल ठीक-ठीक दिखने वाला कोड नहीं है। यह बदलाव के प्रभावों की बात है। यह आमतौर पर जाना जाता है कि यदि आप एक हेडर को अपरिवर्तित रखते हैं और बस एक कार्यान्वयन (.cpp)फ़ाइल बदलते हैं , तो इसे अन्य स्रोत के पुनर्निर्माण की आवश्यकता नहीं होगी क्योंकि कोई साइड इफेक्ट नहीं होना चाहिए।

यह दस्तक-प्रभाव के बारे में चिंता किए बिना ऐसे परिवर्तन करने के लिए "सुरक्षित" बनाता है और वास्तव में "स्थिरता" का मतलब है।


-1

स्नोमैन के उदाहरण के लिए आपको थोड़ा विस्तार की आवश्यकता है कि आपको वास्तव में .h फ़ाइलों की आवश्यकता क्यों है।

नाटक में एक और वर्ग बार जोड़ें जो वर्ग फू पर भी निर्भर है।

Foo.h -> में कक्षा फू के लिए घोषणा शामिल है

Foo.cpp -> वर्ग फू की परिभाषा (प्रतिगमन) शामिल है

Main.cpp -> Foo प्रकार के चर का उपयोग करता है।

Bar.cpp -> प्रकार फू के चर का भी उपयोग करता है।

अब सभी cpp फ़ाइलों को Foo.h को शामिल करने की आवश्यकता है। Foo.cpp को एक से अधिक cpp फ़ाइल में शामिल करना एक त्रुटि होगी। लिंकर विफल होगा क्योंकि कक्षा फू को एक से अधिक बार परिभाषित किया जाएगा।


1
वह भी नहीं है। इसे ठीक उसी तरह से हल किया जा सकता है जिस तरह से इसे .hफाइलों में हल किया जाता है - जिसमें गार्ड शामिल हैं और बिल्कुल वैसी ही समस्या है जैसी आपके पास .hफ़ाइलों के साथ है। यह वह नहीं है जो .hफाइलें सभी के लिए हैं।
बेंजामिन Gruenbaum

मुझे यकीन नहीं है कि आप कैसे गार्ड का उपयोग करेंगे शामिल हैं क्योंकि वे प्रति फ़ाइल केवल काम करता है (जैसे प्रीप्रोसेसोड करता है)। इस मामले में चूंकि Main.cpp और Bar.cpp अलग-अलग फाइलें हैं। Foo.cpp को उन दोनों में केवल एक बार शामिल किया जाएगा (संरक्षित या इससे कोई फर्क नहीं पड़ता)। Main.cpp और Bar.cpp दोनों संकलन करेंगे। लेकिन लिंक त्रुटि अभी भी वर्ग फू की दोहरी परिभाषा के कारण होती है। हालाँकि वहाँ भी विरासत है जिसका मैंने उल्लेख भी नहीं किया था। बाहरी मॉड्यूल (dll) आदि के लिए घोषणा
SkarjFace 16

नहीं, यह एक संकलन इकाई होगी, जब से आप .cppफ़ाइल को शामिल करते हैं, तब कोई भी लिंकिंग नहीं होगी ।
बेंजामिन ग्रुएनबाम

मैंने यह नहीं कहा कि यह संकलन नहीं होगा। लेकिन यह एक ही निष्पादन योग्य में main.o और bar.o दोनों को लिंक नहीं करेगा। लिंक किए बिना क्या बात है सबको संकलित करने में।
स्कारर्जफास

उह ... चलाने के लिए कोड मिल रहा है? आप अभी भी इसे लिंक कर सकते हैं, लेकिन सिर्फ फाइलों को एक-दूसरे से लिंक नहीं कर सकते - बल्कि वे एक ही संकलन इकाई होंगे।
बेंजामिन ग्रुएनबाम

-2

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

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