क्या एक विरासत कार्य के लिए एक अलग रिटर्न प्रकार के साथ वर्चुअल फ़ंक्शन को लागू करना संभव है (टेम्पलेट का उपयोग वापस नहीं कर रहा है)?सी ++ आभासी फ़ंक्शन रिटर्न प्रकार
उत्तर
कुछ मामलों में, हाँ, मूल व्यय प्रकार के साथ वापसी प्रकार covariant के रूप में एक अलग रिटर्न प्रकार का उपयोग करके वर्चुअल फ़ंक्शन को ओवरराइड करने के लिए एक व्युत्पन्न वर्ग के लिए कानूनी है। उदाहरण के लिए, निम्नलिखित पर विचार:
class Base {
public:
virtual ~Base() {}
virtual Base* clone() const = 0;
};
class Derived: public Base {
public:
virtual Derived* clone() const {
return new Derived(*this);
}
};
यहाँ, Base
एक शुद्ध आभासी समारोह clone
कहा जाता है कि एक Base *
रिटर्न परिभाषित करता है। व्युत्पन्न कार्यान्वयन में, यह वर्चुअल फ़ंक्शन Derived *
के रिटर्न प्रकार का उपयोग करके ओवरराइड किया गया है। हालांकि वापसी प्रकार आधार में के रूप में ही नहीं है, यह पूरी तरह से सुरक्षित है, क्योंकि किसी भी समय आप
Base* ptr = /* ... */
Base* clone = ptr->clone();
लिखना होता है clone()
करने के लिए कॉल हमेशा एक Base
वस्तु के लिए एक सूचक वापस आ जाएगी, क्योंकि भले ही यह एक रिटर्न Derived*
, यह सूचक निश्चित रूप से Base*
पर परिवर्तनीय है और ऑपरेशन अच्छी तरह से परिभाषित है।
अधिक आम तौर पर, फ़ंक्शन का रिटर्न प्रकार कभी भी इसके हस्ताक्षर का हिस्सा नहीं माना जाता है। जब तक रिटर्न टाइप कॉन्वर्सेंट होता है तब तक आप किसी भी सदस्य फ़ंक्शन को किसी भी रिटर्न प्रकार से ओवरराइड कर सकते हैं।
हां। रिटर्न प्रकारों को तब तक अलग होने की अनुमति है जब तक वे covariant हों। सी ++ मानक इस (§10.3/5) की तरह यह वर्णन करता है:
एक अधिभावी समारोह की वापसी प्रकार ओवरराइड समारोह की वापसी प्रकार या कार्यों की कक्षाओं के साथ covariant के लिए या तो समान होगा। एक समारोह
D::f
एक समारोहB::f
ओवरराइड करता है, तो कार्य की वापसी प्रकार covariant कर रहे हैं निम्नलिखित मानदंडों को पूरा:
- दोनों वर्गों की ओर इशारा या वर्गों 98)
- में वर्ग के लिए संदर्भ
B::f
की वापसी प्रकारD::f
की वापसी प्रकार में वर्ग के रूप में एक ही कक्षा है या,D::f
की वापसी प्रकार में वर्ग का एक स्पष्ट प्रत्यक्ष या अप्रत्यक्ष आधार वर्ग है औरD
- दोनों संकेत में पहुँचा जा सकता है या संदर्भ है
D::f
के रिटर्न प्रकार में समान सीवी-योग्यता और वर्ग प्रकार मेंB::f
के रिटर्न प्रकार में कक्षा प्रकार की तुलना में समान सीवी-योग्यता के समान सीवी-योग्यता है।
फ़ुटनोट 98 बाहर है कि अंक "वर्ग या वर्गों के लिए बहु स्तरीय संकेत के लिए संदर्भ के लिए बहु स्तरीय संकेत की अनुमति नहीं है।"
संक्षेप में, यदि D
B
की एक उप-प्रकार है, तो D
में समारोह की वापसी प्रकार B
में समारोह की वापसी प्रकार का एक उप-प्रकार की जरूरत है। सबसे आम उदाहरण यह है कि जब रिटर्न प्रकार स्वयं D
और B
पर आधारित होते हैं, लेकिन उन्हें होने की आवश्यकता नहीं होती है। इस पर विचार करें, जहां हम दो अलग-अलग प्रकार के पदानुक्रम:
struct Base { /* ... */ };
struct Derived: public Base { /* ... */ };
struct B {
virtual Base* func() { return new Base; }
virtual ~B() { }
};
struct D: public B {
Derived* func() { return new Derived; }
};
int main() {
B* b = new D;
Base* base = b->func();
delete base;
delete b;
}
कारण यह काम करता है क्योंकि func
के किसी भी फोन करने वाले एक Base
सूचक उम्मीद कर रही है। कोई भी Base
सूचक करेगा। इसलिए, यदि D::func
हमेशा Derived
पॉइंटर वापस करने का वादा करता है, तो यह हमेशा पूर्वजों वर्ग द्वारा निर्धारित अनुबंध को पूरा करेगा क्योंकि Derived
सूचक को Base
पॉइंटर में रूपांतरित किया जा सकता है। इस प्रकार, कॉलर्स हमेशा वे उम्मीद करेंगे जो वे उम्मीद करते हैं।
वापसी प्रकार अलग-अलग करने के लिए अनुमति के अलावा, कुछ भाषाओं पैरामीटर प्रकार अधिभावी समारोह भिन्न करने की भी अनुमति देते हैं। जब वे ऐसा करते हैं, तो उन्हें आमतौर पर contravariant होने की आवश्यकता होती है। यही है, यदि B::f
Derived*
स्वीकार करता है, तो D::f
को Base*
स्वीकार करने की अनुमति होगी। Descendants looser होने की अनुमति दी जाती है, और वे कठोर जो वे वापस लौटते हैं। सी ++ पैरामीटर-प्रकार contravariance की अनुमति नहीं देता है। यदि आप पैरामीटर प्रकार बदलते हैं, तो सी ++ इसे एक नया नया फ़ंक्शन मानता है, इसलिए आप ओवरलोडिंग और छिपाने लगते हैं।इस विषय पर अधिक जानकारी के लिए, विकिपीडिया में Covariance and contravariance (computer science) देखें।
ठीक है, मैंने आज कुछ सीखा। +1। –
क्या यह वास्तविक सुविधा या रिटर्न प्रकार से दुष्प्रभाव का उपयोग नहीं किया जा रहा है? –
@ मार्टिन, निश्चित रूप से एक सुविधा। मुझे यकीन है कि ओवरलोड रिज़ॉल्यूशन के साथ इसके साथ कुछ लेना देना नहीं था। यदि आप फ़ंक्शन ओवरराइड कर रहे हैं तो वापसी प्रकार * है * उपयोग किया जाता है। –
वर्चुअल फ़ंक्शन के व्युत्पन्न क्लास कार्यान्वयन में Covariant Return Type हो सकता है।
- 1. सी ++ टेम्पलेट फ़ंक्शन रिटर्न प्रकार
- 2. आभासी कार्यों के लिए अलग-अलग रिटर्न प्रकार
- 3. फ़ंक्शन का डायनामिक रिटर्न प्रकार
- 4. पेडेंटिक जीसीसी चेतावनी: फ़ंक्शन रिटर्न प्रकार
- 5. सी # रिटर्न अलग-अलग प्रकार?
- 6. सी # में टेम्पलेट फ़ंक्शन - रिटर्न टाइप?
- 7. सी ++ आभासी फ़ंक्शन कॉल बनाम बूस्ट :: फ़ंक्शन कॉल speedwise
- 8. गैर-इकाई रिटर्न प्रकार
- 9. सी ++ "आभासी कार्यों, लेकिन कोई आभासी विनाशकर्ता"
- 10. सी रिटर्न में क्या स्कैनफ फ़ंक्शन?
- 11. सी # प्रकार तर्कों का उपयोग एकाधिक रिटर्न
- 12. सी ++ में नया प्रकार का रिटर्न प्रकार क्या है?
- 13. सी ++ आभासी विरासत
- 14. सी ++: निजी आभासी कार्यों बनाम शुद्ध आभासी कार्यों
- 15. टेम्पलेट्स के लिए ऑपरेटर/फ़ंक्शन का डेडस रिटर्न प्रकार
- 16. "जेनेरिक फ़ंक्शन" के रिटर्न प्रकार को निर्धारित करना
- 17. सी में बुलियन रिटर्न प्रकार की अनुमति है?
- 18. कॉलर फ़ंक्शन रिटर्न मान
- 19. पावरशेल फ़ंक्शन रिटर्न व्यवहार
- 20. PHP फ़ंक्शन रिटर्न सरणी
- 21. आप एक रिटर्न प्रकार
- 22. डब्ल्यूसीएफ रिटर्न प्रकार
- 23. रिटर्न प्रकार पर ओवरलोडिंग?
- 24. शून्य रिटर्न प्रकार
- 25. विधि रिटर्न प्रकार
- 26. प्रकार 'System.Int32' का अभिव्यक्ति रिटर्न प्रकार 'System.Object'
- 27. सी ++ आभासी विधि ओवरराइड
- 28. सी ++: "आभासी" सभी सन्तान
- 29. सी ++ आभासी विधि
- 30. फ़ंक्शन वापसी के बिना फ़ंक्शन रिटर्न मूल्य
यह "आप किसी भी प्रकार के रिटर्न प्रकार के साथ किसी सदस्य फ़ंक्शन को ओवरराइड कर सकते हैं" सही नहीं है। जब तक रिटर्न टाइप समान या कॉन्वर्सेंट (जिसे आपने समझाया), अवधि तक आप ओवरराइड कर सकते हैं। यहां कोई और सामान्य मामला नहीं है। – bronekk
@ bronekk- आपके द्वारा उद्धृत शेष वाक्य में कहा गया है कि नए रिटर्न प्रकार को मूल प्रकार कहीं भी उपयोग करने योग्य होना चाहिए; यही है, नया प्रकार मूल के साथ covariant है। – templatetypedef
कि शेष वाक्य सही नहीं है; 'base *' 'long' 'और' derived * '' int' के साथ 'बेस *' को बदलने की कल्पना करें (या दूसरी तरफ, कोई फर्क नहीं पड़ता)। यह काम नहीं करेगा। – bronekk