2011-01-28 21 views
10

वर्चुअल फ़ंक्शन का रिटर्न प्रकार बेस क्लास या कॉन्वेंट में समान प्रकार का होना चाहिए। लेकिन हमारे पास यह प्रतिबंध क्यों है?आभासी कार्यों के लिए अलग-अलग रिटर्न प्रकार

+0

आप अधिभावी समारोह की वापसी प्रकार की उम्मीद होने की अनुमति दी ...? – curiousguy

उत्तर

5

क्योंकि वापसी मूल्य का उपयोग करने वाला कोड कैसे असंबद्ध प्रकारों के सभी प्रकार के साथ सामना करेगा? उदा .:

class A 
{ 
public: 
    virtual float func(); 
}; 

class B: public A 
{ 
public: 
    virtual char *func(); 
}; 

A *p = (some_condition) ? new A() : new B(); 
p->func(); // Oh no! What is the type? 
+0

हां, असंबंधित प्रकार = खराब। अन्य संबंधित प्रकारों के बारे में क्या? – curiousguy

13
बकवास है कि पीछा करेगा क्योंकि

:

struct foo 
{ 
    virtual int get() const { return 0; } 
}; 

struct bar : foo 
{ 
    std::string get() const { return "this certainly isn't an int"; } 
}; 

int main() 
{ 
    bar b; 
    foo* f = &b; 

    int result = f->get(); // int, right? ...right? 
} 

यह एक व्युत्पन्न वर्ग वापसी कुछ पूरी तरह से असंबंधित है करने के लिए समझदार नहीं है।

+0

चर्चा [चैट करने के लिए ले जाया गया।] (Http://chat.stackoverflow.com/rooms/15288/discussion-between-gmannickg-and-curiousguy) – GManNickG

+0

चैट का निष्कर्ष: ** जीएमएनएनजीजी स्वीकार करता है कि वर्तमान सी ++ नियम जो केवल पॉइंटर्स (या संदर्भ) को आराम दिया जा सकता है। ** – curiousguy

+0

"प्रवेश" नहीं, मैंने इसे पहले स्थान पर कभी भी इनकार नहीं किया ... – GManNickG

3

सी ++ मानक के अनुसार:

एक अधिभावी समारोह की वापसी प्रकार ओवरराइड func- tion या कार्यों की कक्षाओं के साथ covariant की वापसी प्रकार या तो समान होगा। एक समारोह डी :: च ओवरराइड करता है, तो एक समारोह बी :: च, कार्यों का वापसी प्रकार covariant हैं, बशर्ते वे निम्न मानदंडों को पूरा:

1) दोनों वर्गों की ओर इशारा या वर्गों के लिए संदर्भ

2) बी :: एफ के रिटर्न प्रकार में कक्षा डी :: एफ के रिटर्न प्रकार में कक्षा के समान कक्षा है, या कक्षा में अस्पष्ट और सुलभ प्रत्यक्ष या अप्रत्यक्ष आधार वर्ग है वापसी प्रकार का डी :: एफ

3) दोनों पॉइंटर्स या रेफरेंस एस के पास समान सीवी-योग्यता है और डी प्रकार के डी :: एफ के प्रकार के प्रकार में समान प्रकार की सीवी-योग्यता बी/एफ के रिटर्न प्रकार में कक्षा प्रकार की तुलना में समान सीवी-योग्यता है।

+1

प्रश्न पहले से ही प्रतिबंध का अनुमान लगाता है, यह पूछ रहा है कि यह प्रतिबंध क्यों मौजूद है। – GManNickG

1

जवाब बहुत Bjarne Stroustrup के पूछे जाने वाले प्रश्न पर "Why can't I assign a vector<Apple*> to a vector<Fruit*>?" के लिए दिए गए एक के समान है।

वापसी प्रकार को संशोधित करने की क्षमता भाषा की प्रकार की सुरक्षा में एक छेद का कारण बनती है (पॉलिमॉर्फिक प्रकारों से निपटने के दौरान @GManNickG से एक विशिष्ट उदाहरण के लिए जवाब देखें)।

रिटर्न प्रकार को प्रभावित करते समय एक काफी आम स्थिति आदर्श होगी: मूल प्रकार की वर्चुअल विधि से पॉलीमोर्फिक पॉइंटर लौटने पर। उदाहरण के लिए,

class Base { 
public: 
    virtual Base* parent() = 0; 
}; 

class Child : public Base { 
public: 
    Base* parent() override 
    { 
     return parent_; 
    } 
private: 
    Parent* parent_; // Assume `Parent` type exists. 
}; 

यहाँ हम प्रकार की जानकारी है कि Child जानता है के बारे में यह parent_ सदस्य है खो दिया है। यह बहुत सारे कास्टिंग की ओर जाता है, भले ही प्रकार एक बिंदु पर अच्छी तरह से परिभाषित किया गया था। हम इस का उपयोग करते हुए Curiously Recurring Template Parameter (CRTP) मुहावरा हल कर सकते हैं,

template<class ParentType> 
class Base { 
public: 
    virtual ParentType* parent() 
    { 
     return parent_; 
    } 

private: 
    ParentType* parent_; 

}; 

class Child : public Base<Parent> { 
}; 
+0

"_ उत्तर उत्तर देने के लिए बहुत ही समान है" मैं वेक्टर को वेक्टर पर क्यों नहीं दे सकता? "Bjarne Stroustrup के FAQ पर ._" यह किसी भी तरह से समान नहीं है। "_ रिटर्न प्रकार को संशोधित करने की क्षमता भाषा_ की प्रकार की सुरक्षा में एक छेद का कारण बनती है" किसी भी बाधा के बिना वापसी प्रकार ** को संशोधित करने की क्षमता ** स्पष्ट रूप से सुरक्षित नहीं है। यह मूल प्रश्न का उत्तर नहीं देता है "हमारे पास ** यह प्रतिबंध क्यों है **?" नहीं "हमारे पास कोई प्रतिबंध क्यों है?" – curiousguy

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