जबकि आप बताए अनुसार फाइलों को शामिल कर सकते हैं .cpp, यह एक बुरा विचार है।
जैसा कि आपने उल्लेख किया है, घोषणाएं हेडर फाइलों में हैं। कई संकलन इकाइयों में शामिल होने पर ये कोई समस्या नहीं होती हैं क्योंकि इनमें कार्यान्वयन शामिल नहीं होते हैं। किसी फ़ंक्शन या वर्ग के सदस्य की परिभाषा को कई बार शामिल करना सामान्य रूप से एक समस्या का कारण होगा (लेकिन हमेशा नहीं) क्योंकि लिंकर भ्रमित हो जाएगा और एक त्रुटि फेंक देगा।
क्या होना चाहिए प्रत्येक .cppफ़ाइल में कार्यक्रम के सबसेट के लिए परिभाषाएं शामिल हैं, जैसे कि एक वर्ग, तार्किक रूप से संगठित कार्य समूह, वैश्विक स्थैतिक चर (यदि सभी पर संयम से उपयोग करें), आदि।
प्रत्येक संकलन इकाई ( .cppफ़ाइल) में तब जो भी घोषणाएँ होती हैं, उसमें शामिल परिभाषाओं को संकलित करना आवश्यक होता है। यह फ़ंक्शंस का ट्रैक रखता है और इसे संदर्भित करता है लेकिन इसमें सम्मिलित नहीं है, इसलिए लिंकर उन्हें बाद में हल कर सकता है जब वह ऑब्जेक्ट कोड को एक निष्पादन योग्य या लाइब्रेरी में जोड़ता है।
उदाहरण
Foo.h -> कक्षा फू के लिए घोषणा (इंटरफ़ेस) शामिल है।
Foo.cpp -> कक्षा फू के लिए परिभाषा (कार्यान्वयन) शामिल है।
Main.cpp-> मुख्य विधि, कार्यक्रम प्रविष्टि बिंदु शामिल हैं। यह कोड एक फू को तत्काल बदल देता है और इसका उपयोग करता है।
दोनों Foo.cppऔर Main.cppशामिल करने की आवश्यकता है Foo.h। Foo.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, मैं तुरंत मान लेता हूं कि पहले में कक्षा की घोषणा है और दूसरी में परिभाषा है।