अगर मुझे C ++ हेडर फ़ाइलों से नफरत है तो क्या करें?


25

मैं हमेशा हेडर फ़ाइलों के बारे में उलझन में था। वे बहुत अजीब हैं: आप .h फ़ाइल को शामिल करते हैं। जिसमें शामिल नहीं हैं। लेकिन सीपीसी किसी भी तरह संकलित हैं।

हाल ही में मैं एक टीम प्रोजेक्ट में शामिल हुआ, और निश्चित रूप से, .h और .cpp दोनों का उपयोग किया जाता है।
मैं समझता हूं कि यह बहुत महत्वपूर्ण है, लेकिन हम हमारे पास कई वर्गों में से प्रत्येक में प्रत्येक फ़ंक्शन घोषणा को कॉपी-पेस्ट करने के साथ नहीं रह सकते हैं।

मैं 2-फाइल कन्वेंशन को कुशलता से कैसे संभाल सकता हूं?
क्या इसके साथ मदद करने के लिए कोई उपकरण हैं, या स्वचालित रूप से एक फ़ाइल को बदल सकते हैं जो नीचे .h और .cpp के उदाहरण जैसा दिखता है। (विशेष रूप से एमएस वीसी ++ 2010 के लिए)

class A
{
...
    Type f(Type a,Type b)
    {
        //implementation here, not in another file!
    }
...
};

Type f(Type a)
{
     //implementation here
}
...

8
यह प्रश्न कुछ तरीकों से जा सकता है .. "हमें c ++ का उपयोग करते समय हेडर की आवश्यकता क्यों है" या, "क्या आपको लगता है कि एक आधुनिक भाषा जो संकलित होने का मतलब है हेडर का उपयोग करना चाहिए?" यह है के रूप में, यह है तो मैं क्या करूँ "और" नफरत "शीर्षक में है, जो सेट झंडे की अधिकता के बंद।
टिम पोस्ट

4
आपके प्रश्न से ऐसा लगता है जैसे आप C ++ को नहीं समझते हैं, या आप जो भी सिस्टम का उपयोग करते हैं वह इसे कैसे संकलित करता है। इसे ठीक से उपयोग करना सीखें, और फिर अधिक व्यक्तिपरक प्रश्न पूछें।
डेविड थॉर्नले

31
आपका पहला वाक्य इंगित करता है कि आप "हेडर के बारे में सब कुछ नहीं समझते हैं"। .H फ़ाइल को शामिल करने से .cpp फ़ाइल "किसी भी तरह संकलित" नहीं होती है। आप .cpp फ़ाइलों को स्वतंत्र रूप से अपने आप में संकलित करते हैं। यदि आपने संबंधित .cpp को संकलित नहीं किया है, तो संबंधित ऑब्जेक्ट फ़ाइल के बिना हेडर को शामिल करने से लिंकर विफल हो जाएगा।
पॉल बुचर

5
क्या करें? एक और भाषा खोजें अगर यह आपको बहुत परेशान करती है।
पॉल नाथन

5
"कॉपी-पेस्टिंग के साथ नहीं रह सकता" के बारे में: जब भी कोई फ़ंक्शन को अपडेट करता है, तो किसी को सभी जगहों पर अपडेट करना पड़ता है, जहां इसे वैसे भी कहा जाता है। जैसा कि हेडर फ़ाइल में घोषणा की तुलना में कॉलर्स बहुत कठिन हैं, हेडर को अपडेट करना केवल एक मामूली विवरण है।
Sjoerd

जवाबों:


15

अधिक रिफ्लेक्टिंग फ्रेंडली C ++ लिखना

C ++ में आपको हेडर का उपयोग बिल्कुल नहीं करना है। आप पूरे ऑब्जेक्ट को एक फ़ाइल में उसी तरह परिभाषित कर सकते हैं जैसे आप C # या Java के साथ करते हैं। सी डेवलपर्स आमतौर पर केवल हेडर फ़ाइल में बाहरी कॉल रखेंगे। सभी आंतरिक कॉल्स को .c फ़ाइल में परिभाषित किया जाएगा। उसी टोकन के द्वारा, आप अपनी C ++ .h फ़ाइलों को कक्षाओं / इंटरफेस (शुद्ध आभासी अमूर्त कक्षाओं) / आदि के लिए आरक्षित कर सकते हैं। इसका उद्देश्य DLL के बाहर साझा किया जाना है। आंतरिक कक्षाओं / संरचनाओं / इंटरफेस आदि के लिए, आप बस उस .cpp फ़ाइल को शामिल करेंगे, जिसकी आपको आवश्यकता है:

#include<myclass.cpp>

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

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

आप इस प्रश्न को भी देखना चाहेंगे: C ++ के लिए अच्छा रीफैक्टरिंग उपकरण

कैसे C / C ++ हैडर / कार्यान्वयन फ़ाइलें हल करता है

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

.C या .cpp फ़ाइलों का कार्यान्वयन होता है। चूंकि कंपाइलर प्रत्येक कार्यान्वयन फ़ाइल को ऑब्जेक्ट फ़ाइल में परिवर्तित करता है, अकल्पित अवधारणाओं (हेडर में घोषित किया गया) के लिए हुक हैं। लिंकर अन्य ऑब्जेक्ट फ़ाइलों में कार्यान्वयन के लिए हुक लगाता है और एक बड़ा बाइनरी बनाता है जिसमें सभी कोड (साझा पुस्तकालय या निष्पादन योग्य) शामिल होते हैं।

वीएस विशिष्ट

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


समस्या यह है, मैं हर समय कक्षाओं को भारी रूप से संशोधित कर रहा हूं, न कि केवल नए कार्यों को जोड़ रहा हूं, आदि
Oleh Prypin

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

2
वही मैं कर रहा हूँ। मैं में सुधार कर रहा हूँ / "बिल्डिंग ब्लॉक्स" को संशोधित करने और नए लोगों को जोड़ने
ओलेह Prypin

C ++ कभी भी दोस्ताना व्यवहार नहीं करता है। जब तक ऐसे उपकरण नहीं थे, जिन्हें जावा आईडीई में करना बहुत आसान था, तब तक रिफैक्टरिंग की अवधारणा ने गति प्राप्त नहीं की। नोट: वे विशेषताएँ स्मॉलटाक डेवलपर्स और अन्य भाषाओं के लिए थीं, लेकिन यह तब तक मुख्यधारा नहीं बन पाई जब तक कि यह बहुत सारे लोगों के लिए उपलब्ध नहीं थी। अब तक मुझे अभी तक किसी को समझदारी से सी ++ के लिए लागू नहीं करना है। शायद JetBrains से Resharper? मुझे पता है कि यह C # और VB कोड करता है, लेकिन मुझे यकीन नहीं है कि यह आपको C ++ रिफैक्टिंग देगा।
बेरिन लोरिट्श

@Berin: मैं एक या दो साल पहले C ++ रिफ्लेक्टरिंग टूल्स की तलाश में गया था, और दो चीजों को पाया। वे उस समय काफी महंगे थे, और मैंने परीक्षण संस्करण नहीं देखे थे, इसलिए मुझे नहीं पता कि उन्होंने क्या किया। इसके अलावा, किसी ने केवल emacs के साथ काम किया, जो एक विजुअल स्टूडियो शॉप में इसकी प्रभावशीलता को सीमित करेगा।
डेविड थॉर्नले

13

जावा डेवलपर बनें।

यदि आपको वास्तव में C ++ में विकास करना चाहिए, तो आप एक IDE का उपयोग करके देख सकते हैं। अक्सर वे कुछ तंत्र प्रदान करते हैं जिसके द्वारा आप एक वर्ग में एक विधि जोड़ सकते हैं, और यह स्वचालित रूप से घोषणा को .h फ़ाइल में और परिभाषा को .cpp फ़ाइल में रखता है।


2
kthx, मैं कुछ हद तक जावा को जानता हूं, लेकिन आप निम्न-स्तरीय Win32 DLL को इसके साथ नहीं बना सकते, क्या आप कर सकते हैं?
ओलेह प्रिनपिन

41
मुझे पता नहीं क्यों, लेकिन 'एक जावा डेवलपर बनें' किसी भी तरह एक अपमान की तरह लगता है: डी।
ओलिवर वीलर

2
यदि आप निम्न स्तर करना चाहते हैं, तो 'आसान भाषाओं' के बारे में सब कुछ भूल जाएं। निम्न स्तर की लागत पसीना और आँसू है।
बातिबिक्स

5
विशेष रूप से उपयोगी उत्तर नहीं।
ChrisF

1
@OliverWeiler मुझे नहीं लगता कि "एक जावा डेवलपर बनें" एक अपमान के रूप में है। मैं C ++ और Java दोनों में प्रोग्राम करता हूं, लेकिन मेरी प्राथमिकता जावा से है, क्योंकि कोड को बैठाना और काम करना (और अधिक पोर्टेबल) करना बहुत आसान है। यदि आप किसी कारण से हेडर फ़ाइलों के अस्तित्व का पता लगाते हैं, तो जावा की कोशिश करना सही विकल्प हो सकता है (हालांकि यह अजीब है कि आप हेडर फ़ाइलों से नफरत करेंगे; मैं आईडीई में बदलाव पर विचार करूंगा)।
ट्रिक्स वुल्फ

7

आप Hwaci (जो लोग SQLite और जीवाश्म करते हैं) से मेक हेडर्स प्रोग्राम में दिलचस्पी ले सकते हैं ।

जीवाश्म को एक विचार बनाने के लिए कैसे बनाया गया है, इस पर भी एक नज़र डालें ।


5
प्रश्नकर्ता को अभी भी .h और .cpp के बीच के संबंध को समझने की आवश्यकता है।
जॉब

2
मैं मूल बातें समझता हूं। जवाब मुझे वही चाहिए जो मुझे चाहिए।
ओलेह प्रिनपिन

4

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

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


-1

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

यदि यह आपका मामला है, तो मैं " .hpp" (या " .hxx") फ़ाइल एक्सटेंशन या फ़ाइल प्रत्यय का उपयोग करने का सुझाव देता हूं ।

आपको अपने कंपाइलर, डेवलपर एनवायरमेंट या बिल्ट प्रोग्राम को कॉन्फ़िगर करना पड़ सकता है।


3
क्या आप इस बारे में बात कर रहे हैं कि जब आप किसी फाइल को शामिल करते हैं तो कैसे करते हैं #include <iostream>? वे सिर्फ जीसीसी पुस्तकालय के लिए नहीं हैं। वास्तव में, 1997 सी ++ मानक , धारा 17.3.1.2 में इसकी परिभाषा दी गई है। मैं इस तरह से नामकरण फ़ाइलों से बचना होगा। आप कर सकते हैं, लेकिन इसका कारण C ++ मानक पुस्तकालय था जो संभवतः नामकरण संघर्ष से बचने के लिए था। मुझे वास्तव में यह बहुत अजीब लगता है जब कंपाइलर स्वचालित रूप से '.h' जोड़ते हैं जब आप एक हेडर को शामिल करते हैं, तो यह मेरे लिए बहुत अस्थिर लगता है। और मैं कभी भी किसी का नाम हेडर नहीं देखता, बिना प्रत्यय के सी ++ मानक पुस्तकालय को छोड़कर।
वेदोसिटी

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