जबकि आप बताए अनुसार फाइलों को शामिल कर सकते हैं .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
, मैं तुरंत मान लेता हूं कि पहले में कक्षा की घोषणा है और दूसरी में परिभाषा है।