C ++ में इंटरफ़ेस और कार्यान्वयन को व्यवस्थित करने के तरीके


12

मैंने देखा है कि हेडर फ़ाइल में क्या है और cpp फ़ाइल में क्या जाता है, इस बारे में C ++ में कई अलग-अलग प्रतिमान हैं। AFAIK, ज्यादातर लोग, विशेष रूप से एक सी पृष्ठभूमि के लोग, करते हैं:

foo.h

 class foo {
 private:
     int mem;
     int bar();
 public:
     foo();
     foo(const foo&);
     foo& operator=(foo);
     ~foo();
 }

foo.cpp

 #include foo.h
 foo::bar() { return mem; }
 foo::foo() { mem = 42; }
 foo::foo(const foo& f) { mem = f.mem; }
 foo::operator=(foo f) { mem = f.mem; }
 foo::~foo() {}
 int main(int argc, char *argv[]) { foo f; }

हालाँकि, मेरे व्याख्याता आमतौर पर शुरुआती लोगों को इस तरह से C ++ सिखाते हैं:

foo.h

 class foo {
 private:
     int mem;
     int bar() { return mem; }
 public:
     foo() { mem = 42; }
     foo(const foo& f) { mem = f.mem; }
     foo& operator=(foo f) { mem = f.mem; }
     ~foo() {}
 }

foo.cpp

 #include foo.h
 int main(int argc, char* argv[]) { foo f; }
 // other global helper functions, DLL exports, and whatnot

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

मैं किसी भी तरह से प्रो और कोन को इकट्ठा करना चाहता हूं। शायद अभी भी अन्य तरीके हैं?

मेरे रास्ते का एक नुकसान निश्चित रूप से कभी-कभार आगे की घोषणाओं की जरूरत है।


2
foo.cppअब आपकी fooकक्षा से कोई लेना-देना नहीं है और इसे खाली छोड़ दिया जाना चाहिए (हो सकता है, लेकिन #includeआपकी बिल्ड सिस्टम को खुश करने के लिए)।
बेंजामिन बैनियर

2
आपके व्याख्याता पागल हैं।
ऑर्बिट

जवाबों:


16

जबकि दूसरा संस्करण लिखना आसान है, यह कार्यान्वयन के साथ इंटरफ़ेस को मिला रहा है।

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

इसके अलावा आपको कार्यान्वयन विवरणों को उजागर नहीं करना चाहिए , आपको दूसरे संस्करण के साथ अनावश्यक पुनर्संयोजन मिलेगा ।


1
+1 मेरी प्रोफाइल हेडर फ़ाइलों में रखे गए कोड को नहीं लिखती है - यह एक मूल्यवान कारण भी है।
यूजीन

यदि आप इस प्रश्न के मेरे उत्तर को देखते हैं, तो प्रोग्रामर .stackexchange.com /questions/ 4573/… आप देखेंगे कि यह कक्षा के शब्दार्थ पर बहुत कुछ निर्भर करता है, अर्थात इसका उपयोग क्या होगा (विशेष रूप से यदि यह एक उजागर भाग है आपका उपयोगकर्ता इंटरफ़ेस और आपके सिस्टम में कितनी अन्य कक्षाएं सीधे इसका उपयोग करती हैं)।
कैशबैक

3

मैंने इसे दूसरी बार '93 -95 में वापस किया। 5-10 कार्यों / फाइलों के साथ एक छोटे से ऐप को फिर से शुरू करने के लिए कुछ मिनट लगे (उसी 486 पीसी पर .. और नहीं, मुझे कक्षाओं के बारे में भी नहीं पता था, मैं सिर्फ 14-15 साल का था और कोई इंटरनेट नहीं था ) ।

इसलिए, आप जो शुरुआती सिखाते हैं और जो आप पेशेवर रूप से उपयोग करते हैं, वह विशेष रूप से C ++ में बहुत भिन्न तकनीकें हैं।

मुझे लगता है कि सी ++ और एफ 1 कार के बीच तुलना उपयुक्त है। आप शुरुआती लोगों को एफ 1 कार में नहीं डालते हैं (जो कि तब तक शुरू नहीं होता है जब तक कि आप इंजन को 80-95 डिग्री सेल्सियस तक गर्म नहीं करते हैं)।

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


यह उत्तर और भी बेहतर होगा यदि आपने स्थैतिक संकलन / लिंकिंग पर थोड़ा विस्तार किया (मुझे यह पता नहीं था!)
फेलिक्स डॉमबेक

2

दूसरी विधि वह है जिसे मैं पूरी तरह से अंतर्निर्मित कक्षा कहूंगा। आप एक वर्ग परिभाषा लिख ​​रहे हैं, लेकिन इसका उपयोग करने वाले आपके सभी कोड सिर्फ कोड को इनलाइन करेंगे।

हाँ, संकलक तय करता है कि कब इनलाइन और कब नहीं ... इस मामले में आप संकलक को निर्णय लेने में मदद कर रहे हैं, और आप संभावित रूप से कम कोड और संभावित रूप से तेज़ी से उत्पन्न कर रहे हैं।

यह लाभ इस तथ्य से आगे बढ़ने की संभावना है कि यदि आप किसी फ़ंक्शन के कार्यान्वयन को संशोधित करते हैं, तो आपको इसका उपयोग करने वाले सभी स्रोत को फिर से बनाने की आवश्यकता होती है। कक्षा की हल्की प्रकृति में आप कार्यान्वयन को संशोधित नहीं करेंगे। यदि आप एक नई विधि जोड़ते हैं, तो आपको हेडर को वैसे भी संशोधित करना होगा।

हालांकि आपकी कक्षा अधिक जटिल हो जाती है, यहां तक ​​कि एक लूप को जोड़ने पर, इस तरह से करने का लाभ कम हो जाता है।

यह अभी भी अपने फायदे हैं, विशेष रूप से:

  • यदि यह "सामान्य-कार्यक्षमता" कोड है, तो आप केवल हेडर को शामिल कर सकते हैं और बिना किसी पुस्तकालय से लिंक किए बिना कई परियोजनाओं से इसका उपयोग कर सकते हैं जिसमें इसका स्रोत शामिल है।

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

ध्यान दें कि टेम्प्लेट एक विशेष मामला है क्योंकि आपको कार्यान्वयन विवरण शामिल करना है। आप इसे किसी अन्य फ़ाइल में अस्पष्ट कर सकते हैं, लेकिन इसे वहां होना चाहिए। (तात्कालिकता के साथ उस नियम का अपवाद है, लेकिन सामान्य तौर पर आप अपने टेम्पलेट्स को इनलाइन करते हैं)।


1

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

यदि आप हेडर-ओनली लाइब्रेरी लिखना चाहते हैं , तो यह विषय आपकी चिंताओं में से एक है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.