2009-02-10 15 views
5

मैं एक मामूली अनुभवी जावा/सी # प्रोग्रामर हूं, और मैंने हाल ही में सी ++ सीखना शुरू कर दिया है। समस्या यह है कि, मुझे विभिन्न हेडर और कोड फ़ाइलों को कैसे व्यवस्थित करना है, यह समझने में परेशानी हो रही है। यह ज्यादातर समझने की कमी के कारण लगता है कि कैसे संकलक सबकुछ एक साथ जोड़ता है। मैंने कुछ पाठ्यपुस्तकों को पढ़ने की कोशिश की है, लेकिन मेरी पूर्वकल्पनाएं मेरे जावा और सी # ज्ञान द्वारा भारी रंगीन हैं। उदाहरण के लिए, मुझे इस तथ्य के साथ पकड़ने में कठिनाई हो रही है कि विधियों और पसंद को केवल कक्षा परिभाषा के बजाय नामस्थान में परिभाषित किया जा सकता है।जावा/सी # परिप्रेक्ष्य से सी ++ कंपाइलर्स को समझना

मुझे सी ++ -> जावा/सी # मार्गदर्शिकाएं मिली हैं, लेकिन व्यावहारिक रूप से दूसरी तरफ जाने के लिए कुछ भी नहीं है। क्या जावा/सी # -> सी ++ संक्रमण को आसान बनाने के लिए वहां कोई अच्छा संसाधन है, विशेष रूप से संकलन प्रक्रिया को समझने के संबंध में?

+0

संपादित करें: उत्तर देने वाले सभी के लिए धन्यवाद, सभी उत्तर उपयोगी और सूचनात्मक थे। – Whatsit

+0

किसी भी स्थिति में किसी भी स्थिति के लिए, मुझे यह पृष्ठ बहुत उपयोगी पाया गया है, विशेष रूप से सेक्शन ए 3.3 (कक्षाएं): http://www.horstmann.com/ccj2/ccjapp3।एचटीएमएल – Whatsit

उत्तर

4

C++ FAQ सी ++ की सभी idiosyncrasies के बारे में एक उत्कृष्ट संसाधन है, लेकिन संभवतः यह संभवतः थोड़ा अधिक उन्नत है जो आप खोज रहे हैं - अधिकांश प्रश्न (केवल जवाब नहीं) रहस्यों को काफी अनुभवी सी ++ डेवलपर्स के लिए भी हैं ।

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

मैं ऊपर दिए गए आपके विशिष्ट प्रश्नों का उत्तर देने का प्रयास कर सकता हूं, लेकिन मुझे नहीं पता कि मैं कितना अच्छा करूँगा।

हेडर फ़ाइलों और सीपीपी फ़ाइलों के बीच संबंधों को समझने की कुंजी में से एक "अनुवाद इकाई" के विचार को समझ रहा है। एक जावा क्लास फ़ाइल को अनुवाद इकाई माना जा सकता है क्योंकि यह मूल इकाई है जिसे बाइनरी रूप में संकलित किया जाता है। सी ++ में, बहुत सी सीपीपी फ़ाइल एक अनुवाद इकाई है (यदि आप अजीब सामान कर रहे हैं तो अपवाद हैं)।

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

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

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

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

4

यह ऐसा कुछ है जो मुझे भ्रमित कर देता है जब मैंने पहली बार सी का उपयोग करना शुरू किया। पुस्तकें हेडर बनाम कोड फ़ाइलों के सही उपयोग का वर्णन करने का अच्छा काम नहीं करती हैं।

कंपाइलर प्रत्येक .cpp फ़ाइल को लोड करके और अन्य सभी से स्वतंत्र संकलित करके काम करता है। संकलन में पहला कदम # अंतर्निहित बयानों द्वारा संदर्भित सभी शीर्षकों को लोड करना है। आप इसके बारे में सोच सकते हैं कि पूरे foo.h का टेक्स्टल सम्मिलित करना जहां भी #include "foo.h" है।

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

+0

"" शीर्षलेख फ़ाइलों में वर्गों की घोषणाएं शामिल होनी चाहिए " वास्तव में, आप * कक्षाएं परिभाषित करें और * हेडर फाइलों में इसके सदस्य कार्यों को घोषित करें। हालांकि, * परिभाषित * उन सदस्य कार्यों/स्थैतिक सदस्यों को स्रोत फ़ाइलों में किया जाता है । जबकि, कक्षा foo; एक घोषणा है, कक्षा foo {} परिभाषा है। –

1

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

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

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

1

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

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

संबंधित मुद्दे