2012-11-19 11 views
7

शायद मैं एक ही समारोह के नाम और मानकों के साथ दो इंटरफेस है, लेकिन अलग अलग वापसी मूल्यों के साथ:सी ++ विभिन्न रिटर्न प्रकारों के साथ इंटरफेस से एकाधिक विरासत कैसे प्राप्त करें?

struct A { virtual void foo() = 0; }; 
struct B { virtual int foo() = 0; }; 

कैसे क्लास सी परिभाषित करने के लिए, कि यह इंटरफेस विरासत (अगर यह पाठ्यक्रम संभव की है)? उदाहरण के लिए मैं कुछ स्यूडोकोड कि संकलित नहीं है लिखें:

// this code is fake, it doesn't compiled!! 
struct C : A, B 
{ 
    // how to tell compiler what method using if referenced from C? 
    using void foo(); // incorrect in VS 2012 
    // and override A::foo() and B::foo()? 
    virtual void foo() { std::cout << "void C::foo();\n"; } // incorrect 
    virtual int foo() { std::cout << "int C::foo();\n"; return 0; } // incorrect 
} 
// ... for use in code 
C c; 
A &a = c; 
B &b = c; 
c.foo();  // call void C::foo() when reference from C instance 
a.foo();  // call void C::foo() when reference from A instance 
b.foo();  // call int C::foo() when reference from B instance 
+1

आप ऐसा कुछ क्यों चाहते हैं? –

+2

शायद उसके पास ए और बी नहीं है; लेकिन सी को बनाना है जो दोनों लागू करता है। एक उचित प्रश्न लगता है – pm100

+1

सी ++ में यह संभव नहीं है (जैसा कि आपने इसे कोड नहीं किया है)। कार्यों को उनके पैरामीटर प्रकारों द्वारा पहचाना जाता है, न कि उनके रिटर्न प्रकारों से। –

उत्तर

4

यह संभव नहीं है, लेकिन कई विरासत की वजह से नहीं। कक्षा C में foo के अवैध अधिभार के कारण अस्पष्टता उत्पन्न होती है। आपके पास int foo() और void foo() दोनों नहीं हो सकते हैं क्योंकि रिटर्न प्रकार फ़ंक्शन हस्ताक्षर का हिस्सा नहीं है, इस प्रकार संकलक foo पर कॉल को हल करने में सक्षम नहीं होगा। आप A और B कक्षाओं के संघ के रूप में अपना इंटरफ़ेस देख सकते हैं, इसलिए तार्किक रूप से समस्या वास्तविक विरासत से पहले ही मौजूद है। चूंकि कंपाइलर परिप्रेक्ष्य A और B 2 अलग-अलग और असंबंधित प्रकार हैं, इसलिए उन्हें संकलित करते समय कोई समस्या नहीं है और त्रुटि C में वास्तविक एकीकरण के बिंदु तक देरी हो रही है।

समारोह हस्ताक्षर और अधिक भार के बारे में यहाँ अधिक देखें: Is the return type part of the function signature?

1

यह वही हस्ताक्षर (के रूप में @ icepack के जवाब बताते हैं) का उपयोग कर एक आभासी फ़ंक्शन द्वारा दिया गया प्रकार अधिलेखित करने के लिए संभव नहीं है।

एक वैकल्पिक दृष्टिकोण टेम्पलेट बेस क्लास हो सकता है जिसमें टेम्पलेट पैरामीटर के रूप में निर्दिष्ट रिटर्न प्रकार के साथ foo() घोषित किया जा सकता है, और कंक्रीट रिटर्न पैरामीटर प्रकारों के लिए विशेषज्ञता प्रदान करता है।

यह @ डायतरमार कुहल के प्रस्ताव का एक सामान्यीकरण होगा।

1

क्या आप कर सकते हैं कर एक virtual आधार में सभी साझा सामान डाल करने के लिए है, C_base कहना और प्रत्येक सहायक कक्षाओं में परस्पर विरोधी virtual कार्यों को ओवरराइड,। चूंकि C के लिए साझा सामग्री C_base में आसानी से उपलब्ध है, इसलिए सबसे अधिक व्युत्पन्न C में अनिवार्य रूप से उपलब्ध है। अंत में, आप C वर्ग सिर्फ इसलिए वर्ग चीजों को एक साथ खींच:

struct A { virtual void foo() = 0; }; 
struct B { virtual int foo() = 0; }; 

struct C_base { int all_data; }; 

struct A_aux: virtual C_base, A { 
    void foo() { std::cout << "A_aux::foo()\n"; } 
}; 

struct B_aux: virtual C_base, B { 
    int foo() { std::cout << "B_aux::foo()\n"; return 0; } 
}; 

struct C : A_aux, B_aux 
{ 
    using A_aux::foo; 
}; 
2

आप स्पष्ट रूप से अर्हता प्राप्त कर सकते हैं।

class C : A, B { 
public: 
    void A::foo() { ... } 
    int B::foo() { ... } 
}; 

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

इस बल्कि स्टैंडर्ड से, एक MSVC विस्तार प्रतीत होता है।

+0

मैंने सोचा तो, भी, लेकिन संकलन करने की कोशिश कर रहा है यह मेरे लिए असफल रहा। मुझे सही वाक्यविन्यास नहीं मिला है, फिर भी ... –

+0

मुझे कारण मिला। मुझे लगता है कि यह एक एमएसवीसी विस्तार है।यह अजीब लगता है कि मानक इस मामले को कवर नहीं करेगा (और दोगुना विचित्र है कि एक एमएसवीसी एक्सटेंशन वास्तव में कई कारणों के बजाय छेद को पैच कर रहा होगा: पी)। – Puppy

+0

अच्छी चीजें। 'सी' कक्षा के उदाहरण के माध्यम से उन्हें बुलाए जाने के अलावा किसी भी तरह से? – SomeWittyUsername

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