2009-02-18 14 views
5

पृष्ठभूमिअलग हेडर फाइल - सी ++

मैं एक अमूर्त वर्ग,

class IConverter{ 
    public: 
    virtual void DoConvertion() = 0; 
}; 

कई ठोस वर्ग होगा जो सिर्फ DoConvertion विधि को लागू करता है की तरह कुछ है।

class TextConverter : public IConverter{ 
    public: 
    virtual void DoConvertion(){ 
     // my code goes here 
    } 
}; 

class ImageConverter : public IConverter{ 
    public: 
    virtual void DoConvertion(){ 
     // my code goes here 
    } 
}; 

इस तरह के कई ठोस कार्यान्वयन होंगे। मैंने एक हेडर फ़ाइल बनाई है, CharacterConverter.h जिसमें अमूर्त वर्ग आईकोनवर्टर है।

प्रश्न

चूंकि मेरे ठोस वर्ग सिर्फ DoConvertion तरीका लागू, यह प्रत्येक ठोस वर्ग के लिए अलग हेडर फाइल बनाने के लिए आवश्यक है? मेरा मतलब है कि इसे छवि कनवर्टर.h, TextConverter.h और इतने सारे ठोस वर्गों के लिए बनाने की आवश्यकता है? इन सभी हेडर फ़ाइलों में आईकोनवर्टर अमूर्त वर्ग जैसे कोड शामिल होंगे।

किसी भी विचार?

+0

एक असंबंधित शैली बिंदु पर, मैं शायद अपने विधि नाम के रूप में वास्तविक शब्द "रूपांतरण" (DoConversion के रूप में) का उपयोग करेंगे। – Joe

+0

DoConvertion विधि का नाम नहीं है। मैंने इसे नमूना दिखाने के लिए यहां रखा है। :) –

+0

आईसीओन्टर वर्चुअल के विनाशक भी बनाते हैं। भले ही आप इसे इनलाइन परिभाषित करें। –

उत्तर

1

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

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

टिप्पणियों के आधार पर, मैं इस तरह एक संरचना की सलाह देते हैं:

IConverter.h ==> IConverter की परिभाषा
Converters.h ==> सभी उपवर्गों
IConverter.cpp की परिभाषा == > IConverter.h और Converters.h शामिल हैं, आईसीओन्वर्टर सार कार्यक्षमता (स्थैतिक फैक्ट्री विधि और किसी भी विरासत कार्यक्षमता) के कार्यान्वयन में
TextConvter.cpp, ImagerConverter.cpp, आदि ==> प्रत्येक सबक्लास के लिए पृथक सीपीपी फ़ाइलें, प्रत्येक आईकोनवर्टर युक्त एच और कन्वर्टर्स.h

यह आपको केवल उन ग्राहकों में IConverter.h शामिल करने की अनुमति देता है जो कारखाने और सामान्य कार्यक्षमता का उपयोग करते हैं। एक ही शीर्षलेख में अन्य सभी परिभाषाओं को रखने से आप समेकित हो सकते हैं यदि वे सभी मूल रूप से समान हैं। अलग सीपीपी फाइलें आपको ब्रायन द्वारा वर्णित संकलक लाभ का लाभ लेने की अनुमति देती हैं। जैसा कि आपने बताया है, आप हेडर फाइलों में उप-वर्ग परिभाषाओं को रेखांकित कर सकते हैं, लेकिन यह वास्तव में आपको कुछ भी नहीं खरीदता है। जब आपका इनलाइन अनुकूलन की बात आती है तो आपका कंपाइलर आमतौर पर आपके से अधिक स्मार्ट होता है।

+0

हाँ। यह उपयुक्त बाल वर्ग बनाने के लिए एक कारखाने का उपयोग करता है। दुर्भाग्य से, मैं इसे एक सीपीपी फ़ाइल में नहीं रख सकता क्योंकि कार्यान्वयन प्रत्येक ठोस वर्ग के लिए लंबा होगा। क्या आप इसे हेडर फाइलों में रखने और सीपीपी फाइलों का उपयोग करने की सलाह देते हैं? मैं प्रदर्शन के मुद्दों के बारे में चिंतित हूं जो इसे ला सकता है। –

+0

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

+0

यह बहुत मददगार है। धन्यवाद –

1

आपको शायद दोनों तरीकों से जवाब मिलेंगे।

मैं कहूंगा, किसी भी छोटे कन्वर्टर्स के लिए, उनमें से सभी को एक .h/.cpp जोड़ी में पर्याप्त होना पर्याप्त है और यह हर एक को एक जोड़ी में विभाजित करने के लिए अधिक है। मुझे लगता है कि एक ही फाइल के भीतर विधियों के समूह के बनाम रखरखाव के रखरखाव का व्यापार इस मामले में इसके लायक है।

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

8

यह आवश्यक नहीं है। यह मूल रूप से एक निर्णय कॉल है।

कार्यान्वयन सरल है प्रत्येक वर्ग के लिए आप उन सभी को एक ज और एक सीपीपी

में डाल सकते हैं कार्यान्वयन थोड़ा अधिक समय है, तो यह एक अलग ज और सीपीपी उपयोग करने के लिए शायद क्लीनर है प्रत्येक के लिए फ़ाइल।

प्रत्येक वर्ग के लिए एक अलग ज/सीपीपी का उपयोग कर के कुछ लाभ:

  • यह कोड का आयोजन किया और रखेंगे साफ
  • कम संकलन काम: कार्यान्वयन में से एक में एक परिवर्तन नहीं होगा अन्य सभी को पुन: संकलित करने की आवश्यकता
  • तेज़ संकलन समय: कई कंपाइलर एक साथ कई फ़ाइलों को संकलित कर सकते हैं जैसे विजुअल स्टूडियो/एमपी स्विच। कई फाइलों के साथ आपके पास एक तेज़ संकलन समय होगा।
  • अन्य फ़ाइलों को केवल वे क्या
  • तेज़ लिंक समय सब कुछ करने के बजाय जरूरत है शामिल कर सकते हैं: समय से लिंक करना कम हो जाएगा वृद्धिशील
  • जोड़ने संस्करण नियंत्रण का उपयोग करते हुए आप एक विशेष व्युत्पन्न वर्ग के लिए पीठ पर केवल परिवर्तन देख सकते हैं की वजह से, बड़े पैमाने पर किए गए सभी परिवर्तनों के माध्यम से जाने के बजाय 1 .h /।सीपीपी फ़ाइल को एक विशेष व्युत्पन्न वर्ग में एक बदलाव खोजने के लिए।
+0

धन्यवाद। कंक्रीट कक्षाओं के लिए कार्यान्वयन थोड़ा लंबा है। इसलिए यदि मैं इसे हेडर फ़ाइल में डालता हूं तो मैं प्रदर्शन अंतर के बारे में चिंतित हूं। –

1

आपको वस्तुओं को बनाने के लिए ठोस वर्गों की परिभाषाओं की आवश्यकता होगी, इसलिए आपको उन परिभाषाओं को कहीं भी .h फ़ाइल में रखना होगा। आप जिस फाइल को डालते हैं वह आपके ऊपर है।

+0

धन्यवाद। यदि मैं प्रत्येक के लिए सीपीपी फ़ाइल बनाने के बिना हेडर फ़ाइल में कंक्रीट क्लास डालता हूं तो क्या यह कोई प्रदर्शन समस्याएं करेगा? मैं केवल एक ही स्थान पर सभी ठोस वर्गों को शामिल करने जा रहा हूं। –

+0

यदि आप प्रत्येक वर्ग का एक .h फ़ाइल में पूर्ण कार्यान्वयन करना चाहते हैं, तो आपको बस प्रत्येक फ़ंक्शन को इनलाइन के रूप में घोषित करने की आवश्यकता है। इसके परिणामस्वरूप थोड़ा कोड ब्लोट हो सकता है, क्योंकि आपको प्रत्येक फ़ाइल में कम से कम एक प्रति प्राप्त होगी जिसे आप इसे कॉल करते हैं - लेकिन आमतौर पर चिंता करने के लिए बहुत अधिक नहीं। तेज भी हो सकता है। –

1

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

1

एक इंटरफ़ेस वर्ग बनाने के मुख्य बिंदुओं में से एक यह है कि ग्राहक ठोस कार्यान्वयन के बजाय अमूर्त इंटरफ़ेस पर निर्भर हो सकते हैं, और फिर आप ग्राहकों को प्रभावित किए बिना कार्यान्वयन को बदलने के लिए स्वतंत्र हैं।

उसी शीर्षलेख फ़ाइलों में ठोस घोषणाओं को डालने के रूप में इंटरफ़ेस घोषणाएं इसे पराजित करती हैं, इसलिए अब यदि आप एक ठोस वर्ग के कार्यान्वयन विवरण को बदलते हैं, तो आपके ग्राहकों को फिर से संकलन करने की आवश्यकता होगी।

1

आप शायद कारखानों या फ़ंक्शन पॉइंटर्स का उपयोग करके बेहतर हो जाएंगे।

हालांकि, एक विशेष रूप से बुरा तरीका है जो आपके कंक्रीट वर्गों को घोषित करने के लिए एक मैक्रो का उपयोग कर रहा है। उदाहरण के लिए:

IConverter.h के तल में निम्नलिखित मैक्रो

#define DECLARE_CONVERTER_CLASS(CLASS_NAME) \ 
class CLASS_NAME : public IConverter\ 
{ \ 
    public: \ 
    CLASS_NAME() {} \ 
    virtual void DoConversion(); \ 
}; \ 
MyConverter1 में

तो शामिल हैं।सीपीपी

DECLARE_CONVERTER_CLASS(MyConverter1) 

virtual void MyConverter1::DoConversion() 
{ 
    ... 
} 

नीरस :-)

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