2010-10-21 17 views
5

मेरे पास एक इंटरफ़ेस क्लास MyFunction है।इंटरफ़ेस से अवांछित फ़ंक्शंस को कैसे हटाएं

virtual bool Eval(int& iReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0; 
virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0; 
virtual bool Eval(char*& zReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0; 

अब, MyFunction के किसी भी कार्यान्वयन केवल मूल्य किस प्रकार इसे वापस करने की जरूरत पर निर्भर करता है इन कार्यों में से एक को लागू करने की आवश्यकता होगी: वहाँ निम्नलिखित हस्ताक्षरों के साथ इस वर्ग में तीन कार्य हैं। लेकिन मुझे अन्य 3 कार्यों को लागू करना होगा, भले ही अन्य दो कार्य इस तरह हों:

virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;} 

जो इतना अच्छा नहीं दिखता है। या, मैं इस तरह के तीनों कार्यों को इंटरफ़ेस में घोषित कर सकता हूं:

virtual bool Eval(int& iReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;} 
virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;} 
virtual bool Eval(char*& zReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;} 

जो बदसूरत दिखता है। इन दोनों की कम बदसूरत क्या है? या ऐसा करने का एक बेहतर तरीका है?

संपादित करें:

डी ईद्भूजर की विधि पर:

#include <iostream> 

using namespace std; 

class Base 
{ 
    public: 
     template<typename T> 
      void F(T){cout << "Type T" << endl;} 
}; 

class Imp : public Base 
{ 
    public: 
     template<int> 
      void F(int){cout << "Type int" << endl;} 
}; 

int main(int argc, char** argv) 
{ 
    Base* pB; 
    Imp oI; 
    pB = &oI; 

    pB->F(1); 
} 

विशेषज्ञता तरह लग रहा है वर्गों में लागू नहीं होता है, हालांकि व्युत्पन्न। चूंकि टेम्पलेट फ़ंक्शन आभासी नहीं हो सकते हैं, यह एक निराशाजनक स्थिति है जो ऐसा लगता है।

+2

आप के लिए हो सकता है कि जो खोज रहे हैं 'बढ़ावा देने :: संस्करण की तरह कुछ है' एक भी समारोह के पैरामीटर के लिए। – GManNickG

+0

कोई बढ़ावा नहीं कृपया। :)। इसका उपयोग नहीं कर सकतेमुझे कुछ चाहिए जो मैं अपने आप बना सकता हूं। – nakiya

+1

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

उत्तर

2

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

एक और संभावना उस से एक रैपर-इंटरफ़ेस बनाना होगा, जो अनियंत्रित 2 विधियों के लिए डिफ़ॉल्ट मान देता है। लेकिन इस मामले में आप 3 इंटरफेस के साथ-साथ (मूल मूल-इंटरफेस -> 4 इंटरफेस कुल) के साथ समाप्त हो जाएंगे। यदि आपके पास मूल इंटरफ़ेस बदलने की कोई संभावना नहीं है तो यह समाधान स्वीकार्य होगा।

+0

हां मैं 'टेम्पलेट कक्षा माईफंक्शन' घोषित कर सकता हूं और तीन विशेषज्ञता का उपयोग कर सकता हूं। लेकिन, समस्या यह है कि मुझे ऑब्जेक्ट्स बनाना है एक संग्रह में कारखाने और दुकान से सभी तीन प्रकारों से। या शायद मुझे इसे देना होगा। – nakiya

+1

तो मैं पहले ऐसा पसंद करूंगा ल्यूशन (कक्षा में विधियों को लागू करना, झूठी वापसी)। एक इंटरफ़ेस जिसका कार्यान्वयन करने की आवश्यकता नहीं है मेरी राय में एक इंटरफ़ेस नहीं है। – MOnsDaR

3

के बाद से वहाँ() Eval में इस्तेमाल किया प्रकार और कार्यान्वयन की संख्या के बीच एक-से-एक मानचित्रण, एक टेम्पलेट सदस्य समारोह काम करना चाहिए।

class MyFunction { 

    template <class T> 
    bool Eval(T& returnVal, size_t szArgumentCount, list<Param> lParameterList) 
     { return false; } 
}; 

फिर उन प्रकारों के लिए विशेषज्ञता लागू करें जो झूठी वापसी नहीं करनी चाहिए।

इस झूठे और तीन कार्यान्वयन कि किसी भी मामले में की जरूरत होगी वापस जाने के लिए केवल एक सामान्य कार्यान्वयन की आवश्यकता है।

+0

+1 अच्छा जवाब। हालांकि, 'MyFunction' के कार्यान्वयन एक साझा ऑब्जेक्ट में रहेंगे। क्या इससे कोई समस्या आती है? – nakiya

+0

यदि कार्यान्वयन को एक ही सदस्य चर (उदाहरण के लिए राज्य को सहेजने के लिए) तक पहुंच की आवश्यकता है तो यह एक समस्या हो सकती है। अन्यथा, यह ठीक होना चाहिए। –

+0

मुझे बहुत स्पष्ट नहीं है। क्या आप थोड़ा और समझा सकते हैं? – nakiya

0

मुझे लगता है कि आप ओवरराइड करने के लिए एक एकल शुद्ध आभासी विधि घोषित करने से बेहतर हो सकता है, लेकिन यह एक साथ भेदभाव संघ या संस्करण/किसी भी प्रकार वापसी की है कि पहली बहस में। फिर प्रत्येक व्युत्पन्न वर्ग उस प्रकार को वापस कर सकता है जो वह चाहता है। आपके वर्तमान तरीके से, आपको कॉल करने के तरीके पर निर्णय लेने की आवश्यकता होगी। एक साथ भेदभाव संघ के साथ, आप केवल एक ही विधि कॉल, लेकिन क्या इसके साथ क्या करने के लिए यह रिटर्न के बाद के बारे में निर्णय लेंगे।

double dd; 
int ii; 
char* ss; 
variant vv; 
ptr->Eval(&vv, ...); 
switch (vv.type) { 
    case DOUBLE: dd = vv.dd; break; 
    case INTEGER: ii = vv.ii; break; 
    case STRING: ss = vv.ss; break; 
} 

जाहिर है मैं त्रुटि जाँच और की तरह छोड़ दिया गया है, लेकिन यह बहुत है कि मैं क्या लगता है कि तुम क्या करने की योजना बना रहे हैं के समान है:

double dd; 
int ii; 
char* ss; 
switch (ptr->type) { 
    case DOUBLE: ptr->Eval(&dd, ...); break; 
    case INTEGER: ptr->Eval(&ii, ...); break; 
    case STRING: ptr->Eval(&ss, ...); break; 
} 

की तरह कुछ हो जाता है।

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