क्या हेडर फ़ाइलों में C ++ परिभाषाएँ रखना एक अच्छा अभ्यास है?


196

C ++ के साथ मेरी व्यक्तिगत शैली में हमेशा एक सम्मिलित फ़ाइल में कक्षा की घोषणाएं शामिल हैं, और एक .cpp फ़ाइल में परिभाषाएँ, बहुत सी तरह सी + हैडर फ़ाइलें, कोड पृथक्करण के लोकी के जवाब में निर्धारित की गई हैं । निश्चित रूप से, इस कारण का एक हिस्सा मुझे पसंद है कि शायद मुझे उन सभी वर्षों के साथ करना है जो मैंने मोडुला -2 और अदा को कोडित करते हुए बिताए हैं, जिनमें से दोनों में विनिर्देशन फ़ाइलों और बॉडी फ़ाइलों के साथ एक समान योजना है।

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

मैं उतना अंगीकार नहीं हूं जितना कि मैं हुआ करता था, इसलिए मैं वास्तव में उसके इस बन्धुत्व पर प्रहार करने के लिए उत्सुक नहीं हूं, जब तक कि मैं उसके साथ कुछ और लोगों को नहीं देखता। तो वास्तव में यह मुहावरा कितना सामान्य है?

बस जवाबों को कुछ संरचना देने के लिए: क्या यह अब रास्ता है , बहुत आम, कुछ सामान्य, असामान्य, या बग-आउट पागल है?


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

मैंने अपनी सारी कक्षा की परिभाषाएँ अब तक हेडर में रखी हैं। केवल पिम्पल वर्गों की परिभाषाएँ अपवाद हैं। मैं केवल हेडर में उन लोगों की घोषणा करता हूं।
जोहान्स स्काउब -

3
हो सकता है कि वह इसके बारे में सोचता हो क्योंकि विजुअल C ++ उस कोड को लिखने के लिए जोर देता है। जब आप एक बटन पर क्लिक करते हैं, तो हेडर फ़ाइल में कार्यान्वयन उत्पन्न होता है। मुझे नहीं पता कि अन्य कारणों से नीचे बताए गए कारणों से Microsoft इसे प्रोत्साहित क्यों करेगा।
WKS

4
@WKS - Microsoft C # में सभी प्रोग्राम करेगा, और C # में, कोई "शीर्ष लेख" बनाम "बॉडी" भेद नहीं है, यह सिर्फ एक फ़ाइल है। अब दोनों C ++ और C # दुनिया में लंबे समय से हैं, C # रास्ता वास्तव में बहुत आसान है।
मार्क लकाटा

1
@MarkLakata - वह वास्तव में उन चीजों में से एक है जो उसने इंगित किया था। मैंने इस तर्क को हाल ही में सुना नहीं है, लेकिन IIRC वह तर्क दे रहा था कि जावा और सी # इस तरह से काम करते हैं, और सी # उस समय बिल्कुल नया था, जिससे यह एक प्रवृत्ति बन गई थी कि जल्द ही सभी भाषाओं का अनुसरण होगा
TED

जवाबों:


209

आपका सहकर्मी गलत है, सामान्य तरीका है और हमेशा हेडर में .cpp फाइलें (या जो भी एक्सटेंशन आपको पसंद है) और घोषणाओं में कोड डालना है।

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

अंत में, जब सभी कोड हेडर होते हैं, तो अक्सर परिपत्र वस्तु संबंध (कभी-कभी वांछित) होना कष्टप्रद होता है।

निचला रेखा, आप सही थे, वह गलत है।

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

संपादित करें: कुछ लोग थोड़ा और स्पष्टीकरण चाहते हैं, यहां "हेडर ओनली" कोड लिखने के डाउनसाइड पर कुछ विचार दिए गए हैं:

यदि आप चारों ओर खोज करते हैं, तो आप काफी लोगों को बढ़ावा देने से निपटने के लिए संकलन समय को कम करने का एक तरीका खोजने की कोशिश करेंगे। उदाहरण के लिए: बूस्ट एसियो के साथ संकलन के समय को कैसे कम किया जाए , जो कि एक 1K फाइल के 14 के संकलन को बढ़ावा देने के साथ देख रहा है। 14s "विस्फोट" नहीं लग सकते हैं, लेकिन यह निश्चित रूप से विशिष्ट की तुलना में बहुत लंबा है और काफी जल्दी जोड़ सकता है। जब एक बड़ी परियोजना के साथ काम कर रहे हैं। हैडर केवल पुस्तकालयों का संकलन समय को काफी औसत दर्जे से प्रभावित करता है। हम इसे सहन कर लेते हैं क्योंकि बढ़ावा इतना उपयोगी है।

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

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

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


16
मुझे पूरा यकीन है कि वह कहाँ से मिल रहा है। जब भी यह आता है तो वह टेम्प्लेट लाता है। उनका तर्क मोटे तौर पर यह है कि आपको निरंतरता के लिए इस तरह से सभी कोड करना चाहिए।
TED

14
यह एक बुरा तर्क है जो वह बना रहा है, अपनी बंदूकों से चिपके
रहिए

11
यदि "निर्यात" कीवर्ड समर्थित है, तो टेम्पलेट परिभाषाएँ CPP फ़ाइलों में हो सकती हैं। यह C ++ का एक अंधेरा कोना है जो आमतौर पर मेरे ज्ञान के सबसे अच्छे संकलन के रूप में लागू नहीं होता है।
आंद्रेई तारानचेंको

2
इस उत्तर के निचले भाग को देखें (उदाहरण के लिए शीर्ष कुछ जटिल है): stackoverflow.com/questions/555330/…
इवान टेरान

3
यह "हुर्रे, कोई लिंकर त्रुटियों पर" इस ​​चर्चा के लिए सार्थक होने लगा।
इवान टेरान

158

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

.H और .cpp फ़ाइलों के बीच पृथक्करण ज्यादातर इस बिंदु पर मनमाना है, लंबे समय से संकलक अनुकूलन का एक इतिहास। मेरी नज़र में, घोषणाएँ हेडर में हैं और परिभाषाएँ कार्यान्वयन फ़ाइल में हैं। लेकिन, यह सिर्फ आदत है, धर्म नहीं।


140
"जिस दिन C ++ कोडर्स इस तरह से सहमत होते हैं ..." केवल एक C ++ कोडर बचेगा!
ब्रायन सुनिश्चित

9
मुझे लगा कि वे पहले से ही रास्ते में सहमत हैं, .h में घोषणाएँ और .cpp में परिभाषाएँ
hasen

6
हम सब अंधे आदमी हैं और C ++ एक हाथी है।
रोडरिक टेलर

आदत? तो गुंजाइश को परिभाषित करने के लिए .h का उपयोग करने के बारे में क्या? किस चीज़ से इसे प्रतिस्थापित किया गया है?
हर्नान एचे

28

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

हेडर फ़ाइलों में कोड होने का एक कारण यह है कि यह आमतौर पर कीवर्ड इनलाइन को ठीक से काम करने के लिए आवश्यक होता है और अन्य सीपीपी फ़ाइलों में डाले जा रहे टेम्पलेट्स का उपयोग करते समय।


1
"यह घोषणाओं के बजाय वास्तविक कोड को बदलने पर हेडर को शामिल करने वाली सभी फाइलों को फिर से तैयार करने पर मजबूर करता है" मुझे लगता है कि यह सबसे वास्तविक कारण है; इस तथ्य के साथ भी जाता है कि हेडर में घोषणाएँ .c फ़ाइलों के कार्यान्वयन की तुलना में कम बार बदलती हैं।
निनाद

20

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

मैं इस दृष्टिकोण से सहमत नहीं हूं, लेकिन यह हो सकता है कि यह कहां से आ रहा है।


मुझे लगता है कि आप इस बारे में सही हैं। जब हम इस पर चर्चा वह हमेशा टेम्पलेट्स के उदाहरण का उपयोग, आप कम या ज्यादा है, जहां है यह करने के लिए। मैं "के साथ" के रूप में अच्छी तरह से असहमत हूँ, लेकिन मेरे विकल्प बल्कि दृढ़ हैं।
TED

1
@ted - टेम्प्लेटेड कोड के लिए आपको कार्यान्वयन को हेडर में रखना होगा। 'निर्यात' कीवर्ड एक संकलक को घोषणा और परिभाषा की परिभाषा का समर्थन करने के लिए एक संकलक की अनुमति देता है, लेकिन निर्यात के लिए समर्थन बहुत ही गैर-मौजूद है। anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf
माइकल बूर

एक हेडर, हाँ, लेकिन इसमें एक ही हेडर होना आवश्यक नहीं है। नीचे देखें अज्ञात जवाब
TED

यह समझ में आता है, लेकिन मैं यह नहीं कह सकता कि मैं पहले उस शैली में आया हूं।
माइकल बूर

14

मुझे लगता है कि आपका सहकर्मी होशियार है और आप सही भी हैं।

मैंने पाया कि उपयोगी चीजें सब कुछ हेडर में डालती हैं:

  1. हेडर और स्रोतों को लिखने और सिंक करने की कोई आवश्यकता नहीं है।

  2. संरचना सादा है और कोई भी परिपत्र निर्भरता कोडर को "बेहतर" संरचना बनाने के लिए मजबूर नहीं करती है।

  3. पोर्टेबल, एक नई परियोजना के लिए एम्बेडेड आसान।

मैं संकलन समय की समस्या से सहमत हूं, लेकिन मुझे लगता है कि हमें इस पर ध्यान देना चाहिए:

  1. स्रोत फ़ाइल के परिवर्तन से हेडर फ़ाइलों को बदलने की बहुत संभावना है जो पूरे प्रोजेक्ट की ओर फिर से पुन: व्यवस्थित हो सकती हैं।

  2. पहले की तुलना में संकलन गति बहुत तेज है। और यदि आपके पास लंबे समय और उच्च आवृत्ति के साथ निर्मित होने वाली परियोजना है, तो यह इंगित कर सकता है कि आपकी परियोजना के डिजाइन में खामियां हैं। कार्यों को अलग-अलग परियोजनाओं में विभाजित करें और मॉड्यूल इस समस्या से बच सकते हैं।

अंत में मैं सिर्फ अपने सहकर्मी का समर्थन करना चाहता हूं, सिर्फ अपने व्यक्तिगत विचार में।


3
+1। कोई भी नहीं, लेकिन आपको यह विचार था कि हेडर में केवल लंबे समय तक संकलन परियोजना बहुत अधिक निर्भरता के लिए संकेत दे सकती है जो खराब डिजाइन है। अच्छी बात! लेकिन क्या इन निर्भरताओं को एक हद तक हटाया जा सकता है जहां संकलन समय वास्तव में कम है?
तोबिसीमांबी

@TobiMcNamobi: मुझे खराब डिजाइन निर्णयों पर बेहतर प्रतिक्रिया पाने के लिए "सुस्त" के विचार से प्यार है। हालाँकि हेडर-ओनली बनाम अलग से संकलित होने की स्थिति में, यदि हम उस विचार पर समझौता करते हैं तो हम एक संकलन इकाई और विशाल संकलन समय के साथ समाप्त होते हैं। यहां तक ​​कि जब डिजाइन वास्तव में महान है।
जो सो

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

1
मुझे आश्चर्य है कि अगर आधुनिक भाषाओं की तरह पूरी तरह से हेडर छोड़ने के लिए कोई कमियां हैं, तो मुझे आश्चर्य होगा।
जो सो

12

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

याद रखें: एक मूर्खता की प्रवृत्ति छोटे दिमागों की हॉजोब्लिन है


हाँ, मैं भी यही करता हूँ। मेरे द्वारा उपयोग किया जाने वाला सामान्य नियम "यदि यह कोड की एक पंक्ति पर फिट बैठता है, तो इसे हेडर में छोड़ दें" की तर्ज पर कुछ प्रतीत होता है।
TED

क्या होता है जब एक पुस्तकालय A<B>एक सीपीपी फ़ाइल में एक टेम्पलेट वर्ग का शरीर प्रदान करता है , और फिर उपयोगकर्ता एक चाहता है A<C>?
jww

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

7

जैसा कि तुओमास ने कहा, आपका हेडर न्यूनतम होना चाहिए। पूरा होने के लिए मैं थोड़ा विस्तार करूंगा।

मैं अपनी C++परियोजनाओं में व्यक्तिगत रूप से 4 प्रकार की फ़ाइलों का उपयोग करता हूं :

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

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

इसका मतलब है कि मैं #includeअपने हेडर में एक निर्देश पर आगे की घोषणा को प्राथमिकता देता हूं जब भी मैं उनके साथ दूर हो सकता हूं।

अंत में, मैं एक दृश्यता नियम का भी उपयोग करता हूं: मैं अपने प्रतीकों के स्कोप को यथासंभव सीमित करता हूं ताकि वे बाहरी स्कोप को प्रदूषित न करें।

इसे पूरी तरह से लाना:

// example_fwd.hpp
// Here necessary to forward declare the template class,
// you don't want people to declare them in case you wish to add
// another template symbol (with a default) later on
class MyClass;
template <class T> class MyClassT;

// example.hpp
#include "project/example_fwd.hpp"

// Those can't really be skipped
#include <string>
#include <vector>

#include "project/pimpl.hpp"

// Those can be forward declared easily
#include "project/foo_fwd.hpp"

namespace project { class Bar; }

namespace project
{
  class MyClass
  {
  public:
    struct Color // Limiting scope of enum
    {
      enum type { Red, Orange, Green };
    };
    typedef Color::type Color_t;

  public:
    MyClass(); // because of pimpl, I need to define the constructor

  private:
    struct Impl;
    pimpl<Impl> mImpl; // I won't describe pimpl here :p
  };

  template <class T> class MyClassT: public MyClass {};
} // namespace project

// example_impl.hpp (not visible to clients)
#include "project/example.hpp"
#include "project/bar.hpp"

template <class T> void check(MyClass<T> const& c) { }

// example.cpp
#include "example_impl.hpp"

// MyClass definition

यहाँ जीवनरक्षक यह है कि अधिकांश बार अग्रगामी शीर्ष लेख बेकार है: केवल कार्यान्वयन के मामले में typedefया templateतो आवश्यक है और कार्यान्वयन हेडर है;)


6

अधिक मज़ा जोड़ने के लिए आप उन .ippफ़ाइलों को जोड़ सकते हैं जिनमें टेम्पलेट कार्यान्वयन (जिसमें शामिल किया जा रहा है .hpp), जबकि .hppइंटरफ़ेस शामिल है।

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


यही मैंने टेम्पलेट परिभाषाओं के साथ भी लिया (हालांकि मुझे यकीन नहीं है कि मैंने उसी एक्सटेंशन का उपयोग किया है ... थोड़ी देर हो गई है)।
TED

5

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


4

यदि यह नया तरीका वास्तव में मार्ग है , तो हम अपनी परियोजनाओं में अलग दिशा में चल रहे हैं।

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

जब हम लागू होते हैं तब भी हम "अपारदर्शी सूचक" का उपयोग करते हैं।

इन प्रथाओं से हम अपने अधिकांश साथियों की तुलना में तेजी से निर्माण कर सकते हैं। और हाँ ... कोड या वर्ग के सदस्यों को बदलने से बहुत बड़े पुनर्निर्माण नहीं होंगे।


4

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

// class-declaration

// inline-method-declarations

मुझे क्लास के साथ तरीकों के लिए कोड मिश्रण करना पसंद नहीं है क्योंकि मुझे चीजों को जल्दी से देखने के लिए दर्द होता है।

मैं हेडर फ़ाइल में सभी विधियों को नहीं डालूँगा। संकलक (सामान्य रूप से) वर्चुअल विधियों को इनलाइन करने में सक्षम नहीं होगा और (संभावना) केवल छोरों के बिना छोटे तरीकों को इनलाइन करेगा (पूरी तरह से संकलक पर निर्भर करता है)।

कक्षा में विधियां करना मान्य है ... लेकिन देखने की बात से मुझे यह पसंद नहीं है। हेडर में विधियों को डालने का मतलब यह है कि, जब संभव हो, वे इनलेट हो जाएंगे।


2

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


2

मैंने सभी कार्यान्वयन को कक्षा की परिभाषा से बाहर रखा। मैं कक्षा की परिभाषा के बारे में doxygen टिप्पणी करना चाहता हूं।


1
मुझे पता है कि यह देर हो चुकी है, लेकिन डाउनवोटर्स (या सहानुभूति) टिप्पणी करने के लिए परवाह करते हैं क्यों? यह मेरे लिए एक उचित कथन जैसा लगता है। हम Doxygen का उपयोग करते हैं, और मुद्दा निश्चित रूप से सामने आया।
TED

2

मुझे लगता है कि अपने सभी फ़ंक्शन परिभाषाओं को हेडर फ़ाइल में डालना बिल्कुल बेतुका है। क्यों? क्योंकि हेडर फ़ाइल का उपयोग आपकी कक्षा में सार्वजनिक इंटरफ़ेस के रूप में किया जाता है। यह "ब्लैक बॉक्स" के बाहर है।

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


1

क्या यह वास्तव में सिस्टम की जटिलता और घर में होने वाले सम्मेलनों पर निर्भर नहीं करता है?

फिलहाल मैं एक तंत्रिका नेटवर्क सिम्युलेटर पर काम कर रहा हूं जो अविश्वसनीय रूप से जटिल है, और स्वीकृत शैली जिसे मैं उपयोग करने की उम्मीद कर रहा हूं वह है:

Classname.h में कक्षा परिभाषाएँ
classnameCode.h
निष्पादन योग्य कोड classname.cpp में वर्ग कोड

यह डेवलपर-निर्मित बेस कक्षाओं से उपयोगकर्ता-निर्मित सिमुलेशन को विभाजित करता है, और स्थिति में सबसे अच्छा काम करता है।

हालाँकि, मुझे यह देखकर आश्चर्य होगा कि लोग ऐसा करते हैं, कहते हैं, एक ग्राफिक्स अनुप्रयोग, या कोई अन्य अनुप्रयोग जिसका उद्देश्य उपयोगकर्ताओं को एक कोड आधार प्रदान करना नहीं है।


1
"क्लास कोड" और "निष्पादन योग्य कोड" के बीच अंतर क्या है?
टेड

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

आम तौर पर, आप किसी भी कार्यक्रम के विशाल बहुमत (यदि संपूर्णता नहीं) के लिए "वास्तव में अपने आप से कुछ भी नहीं कर सकते" नहीं कह सकते थे? क्या आप कह रहे हैं कि "मुख्य" कोड एक सीपी में जाता है, लेकिन कुछ और नहीं करता है?
TED

इस स्थिति में यह थोड़ा अलग है। जो कोड हम लिखते हैं वह मूल रूप से एक पुस्तकालय है, और उपयोगकर्ता इसके ऊपर अपने सिमुलेशन का निर्माण करते हैं, जो वास्तव में चलने योग्य हैं। इसके बारे में सोचो जैसे कि ओपनगेल -> आपको फ़ंक्शंस और ऑब्जेक्ट्स का एक गुच्छा मिलता है लेकिन बिना cpp फ़ाइल के जो उन्हें चला सकते हैं वे बेकार हैं।
एड जेम्स

0

टेम्पलेट कोड केवल हेडर में होना चाहिए। इसके अलावा इनलाइन को छोड़कर सभी परिभाषाएँ .cpp में होनी चाहिए। इसके लिए सबसे अच्छा तर्क std पुस्तकालय कार्यान्वयन होगा जो उसी नियम का पालन करता है। आप इस बात से असहमत नहीं होंगे कि std lib डेवलपर्स इस बारे में सही होंगे।


कौन सी stdlibs? GCC के libstdc++लगता है (AFAICS) एक हेडर में 'होना चाहिए' या नहीं, srcलगभग कुछ भी includeनहीं है। इसलिए मुझे नहीं लगता कि यह एक सटीक / उपयोगी उद्धरण है। वैसे भी, मुझे नहीं लगता कि stdlibs उपयोगकर्ता कोड के लिए एक मॉडल के बहुत सारे हैं: वे स्पष्ट रूप से उच्च कुशल कोडर्स द्वारा लिखे गए हैं, लेकिन उपयोग किए जाने के लिए , पढ़ा नहीं जाता है : वे उच्च जटिलता को दूर करते हैं जो अधिकांश कोडर के बारे में सोचने की आवश्यकता नहीं होनी चाहिए , _Reserved __namesउपयोगकर्ता के साथ संघर्ष से बचने के लिए हर जगह बदसूरत जरूरत है , टिप्पणियाँ और रिक्ति नीचे है जो मैं सलाह दूंगा, आदि वे एक संकीर्ण तरीके से अनुकरणीय हैं।
अंडरस्कोर_ड

0

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

वैसे, टेड, क्या आपने कई वर्षों पहले लिखे CLIPS पुस्तकालय के लिए Ada बाइंडिंग के हालिया प्रश्न पर इस मंच पर एक नज़र डाली है और जो अब उपलब्ध नहीं है (प्रासंगिक वेब पेज अब बंद हैं)। यहां तक ​​कि अगर एक पुराने क्लिप्स संस्करण के लिए बनाया गया है, तो यह बाइंडिंग किसी Ada 2012 प्रोग्राम के भीतर CLIPS इंट्रेंस इंजन का उपयोग करने के इच्छुक किसी व्यक्ति के लिए एक अच्छा उदाहरण हो सकता है।


1
जबरदस्त हंसी। 2 साल बाद, यह किसी को पकड़ने का एक अजीब तरीका है। यदि मेरे पास अभी भी एक प्रति है, तो मैं जांच करूंगा, लेकिन सबसे अधिक संभावना नहीं है। मैंने एआई वर्ग के लिए ऐसा किया ताकि मैं अपना कोड एडीए में कर सकूं, लेकिन जानबूझकर उस प्रोजेक्ट को CC0 (अनिवार्य रूप से बिना लाइसेंस वाला) बना दिया गया, उम्मीद है कि कोई बेशर्मी से इसे लेगा और इसके साथ कुछ करेगा।
TED
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.