2012-06-26 5 views
6

मैं कह रहा मैं समझता हूँ कि यह है कि केवल nonstatic सदस्य कार्यों आभासी हो सकता है द्वारा शुरू करेंगे, लेकिन यह मैं क्या चाहते है:स्टेटिक फ़ंक्शन ओवरलोडिंग?

  1. एक आधार वर्ग एक अंतरफलक को परिभाषित: तो मैं कार्यों का उपयोग करने के आधार वर्ग संकेत का उपयोग कर सकते ।
  2. स्मृति प्रबंधन उद्देश्यों के लिए (यह सीमित राम के साथ एक एम्बेडेड सिस्टम है) मैं ओवरराइडिंग कार्यों को आवंटित करना चाहता हूं। मैं इस परिणाम को स्वीकार करता हूं कि स्थिर कार्य के साथ, इस कार्य में डेटा को कैसे छेड़छाड़ की जा सकती है, इस पर बाधाएं होंगी।

    मेरी वर्तमान सोच यह है कि मैं इसे एक फ़ंक्शन के लिए एक रैपर बनाकर हल्का ओवरलोडिंग फ़ंक्शन रख सकता हूं जो वास्तव में स्थिर है।

मुझे बता मैं फिर से सोचने के लिए मेरे डिजाइन की जरूरत पूर्वज करें। यही कारण है कि मैं सवाल पूछ रहा हूँ। यदि आप मुझे बताना चाहते हैं कि मैं सी का उपयोग करके बेहतर हूं और कॉलबैक का उपयोग कर रहा हूं, तो कृपया मुझे ऑब्जेक्ट उन्मुख दृष्टिकोण का उपयोग करने के नुकसान की व्याख्या करने के लिए कुछ पढ़ने वाली सामग्री पर निर्देशित करें। क्या डिज़ाइन का एक ऑब्जेक्ट उन्मुख पैटर्न है जो मैंने समझाई गई आवश्यकताओं को पूरा करता है?

+2

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

+0

@ एमवीजी मैं भेद पर आलसी था। ओवरराइडिंग वह है जो मैं कर रहा हूं..मैं इसे संपादित कर दूंगा। – 2NinerRomeo

+0

@ वानडर्ग: तथ्य यह है कि प्रोग्राम एक एम्बेडेड सिस्टम पर चल रहा है, स्टैक स्पेस का उपभोग करने की इच्छा को चला रहा है। मुझे लगता है (लेकिन मैं पहले गलत रहा हूं और मैं इस पर नया हूं) फ़ंक्शन स्थैतिक घोषित करने से कोड को फ्लैश में रखना संभव हो सकता है। – 2NinerRomeo

उत्तर

7

क्या डिज़ाइन का ऑब्जेक्ट उन्मुख पैटर्न है जो मैंने समझाई गई आवश्यकताओं को पूरा करता है?

हां, सादे पुराने वर्चुअल फ़ंक्शंस। आपकी इच्छा "ओवरराइडिंग फ़ंक्शंस को आवधिक रूप से आवंटित किया जाना है।" वर्चुअल फ़ंक्शन स्थिर रूप से आवंटित हैं। यही है, जो कोड कार्यान्वित करता है वह एक बार मौजूद होता है, और केवल एक बार, और संकलन/लिंक समय पर तय किया जाता है। आपके लिंकर कमांड के आधार पर, वे फ्लैश में किसी भी अन्य फ़ंक्शन के रूप में संग्रहीत होने की संभावना है।

class I { 
    public: 
    virtual void doit() = 0; 
    virtual void undoit() = 0; 
}; 

class A : public I { 
    public: 
    virtual void doit() { 
    // The code for this function is created statically and stored in the code segment 
    std::cout << "hello, "; 
    } 
    virtual void undoit() { 
    // ditto for this one 
    std::cout << "HELLO, "; 
    } 
}; 

class B : public I { 
    public: 
    int i; 
    virtual void doit() { 
    // ditto for this one 
    std::cout << "world\n"; 
    } 
    virtual void undoit() { 
    // yes, you got it. 
    std::cout << "WORLD\n"; 
    } 
}; 

int main() { 
    B b; // So, what is stored inside b? 
     // There are sizeof(int) bytes for "i", 
     // There are probably sizeof(void*) bytes for the vtable pointer. 
     // Note that the vtable pointer doesn't change size, regardless of how 
     // many virtual methods there are. 
     // sizeof(b) is probably 8 bytes or so. 
} 
2

स्टेटिक सदस्य कार्यों सिर्फ सादा काम करता है, उस वर्ग के नाम स्थान के अंदर हैं (गैर सदस्य कार्यों की तरह) है। इसका मतलब है कि आप उन्हें सादा कार्यों की तरह व्यवहार कर सकते हैं और निम्नलिखित समाधान करना चाहिए:

class Interface 
{ 
    public: 
    void (*function)(); 
}; 

class Implementation: public Interface 
{ 
    public: 
    Implementation() 
    { 
     function = impl_function; 
    } 

    private: 
    static void impl_function() 
    { 
     // do something 
    } 
}; 

तो

Implementation a; 
Interface* b = &a; 
b->function(); // will do something... 

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

इस प्रकार, मैं आपको बस ऐसा करने की सलाह नहीं दूंगा, और सामान्य आभासी तरीकों का उपयोग करूंगा।

2
स्मृति प्रबंधन प्रयोजनों के लिए

मैं अधिभावी कार्यों स्थिर आवंटित होना चाहते हैं (इस के साथ सीमित राम एक एम्बेडेड सिस्टम है)।

सी ++ में सभी फ़ंक्शंस हमेशा आवंटित किए जाते हैं। एकमात्र अपवाद यह है कि यदि आप मैन्युअल रूप से एक जेआईटी डाउनलोड और उपयोग करते हैं।

0

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

मेरा मुद्दा यह है कि वर्चुअल फ़ंक्शंस का प्रति-ऑब्जेक्ट ओवरहेड वही है, चाहे आपके पास कितने वर्चुअल फ़ंक्शन हों, या उनमें कितना कोड शामिल है। एक बार जब आप यह तय कर लें कि आप कुछ डिग्री बहुरूपता चाहते हैं तो आपके वर्चुअल फ़ंक्शंस को व्यवस्थित करने के तरीके से आपकी स्मृति खपत पर थोड़ा असर होना चाहिए।