2017-03-20 3 views
8

कुछ दिन पहले, मैं सी ++ दुनिया में कूदना चाहता था। मैं आधार और व्युत्पन्न वर्ग अवधारणाओं का अध्ययन कर रहा हूं। क्या कोई निम्नलिखित दो कोड स्निपेट के साथ चल रहा है?बेस और व्युत्पन्न कक्षाएं सी ++

class A 
{ 
    private: 
    virtual int GetValue() { return 10; } 

    public: 
    int Calculate() { return GetValue()*1.5; } 
}; 

class B: public A 
{ 
    private: 
    virtual int GetValue() { return 20; } 
}; 

int main() 
{ 
    B b; 
    std::cout << b.Calculate() << std::endl; 

    return 0; 
} 

उत्पादन 30 है, लेकिन 15

class A 
{ 
    private: 
    int m_data; 

    public: 
    A(): m_data(GetValue()) {} 
    int Calculate() { return m_data*1.5; } 
    virtual int GetValue() { return 10; } 
}; 

class B: public A 
{ 
    public: 
    virtual int GetValue() { return 20; } 
}; 

int main() 
{ 
    B b; A* ap; 
    ap=&b; 
    std::cout << ap->Calculate() << std::endl; 

    return 0; 
} 

उत्पादन 15 लेकिन 30

उम्मीद थी किसी को समझाने और मुझे तर्क को समझने में मदद कर सकता हूँ है उम्मीद की गई थी? इस अवधारणा पर मेरी सोच में कुछ गड़बड़ है, लेकिन मैं इसे समझने में असमर्थ हूं।

+2

बताएं कि आपने क्यों सोचा था कि आपका कोड उन मानों को देगा। –

उत्तर

5

पहला मामला:

यह तुच्छ है। आपके पास B का तत्काल उदाहरण है, और आप return GetValue() * 1.5; की गणना करते हैं जो B::GetValue() का उपयोग करता है क्योंकि आपने GetValue() को बेस क्लास में virtual चिह्नित किया है। इसलिए 20 * 1.5 का मूल्यांकन किया जाता है।

दूसरा मामला:

इतना छोटा नहीं है। m_data के लिए मान सेट करने के लिए आप बेस सदस्य प्रारंभकर्ता में GetValue() पर कॉल कर रहे हैं। मानक सी ++ यह बताता है कि बेस क्लास GetValue() विधि उस मामले में कॉल की जाएगी। (कक्षा A कक्षा पूरी तरह से निर्मित होने तक इसका निर्माण नहीं किया जा रहा है B के कारण होने के बारे में अनौपचारिक रूप से सोचें)। इसलिए 10 * 1.5 का मूल्यांकन किया जाता है। दिलचस्प बात यह है कि GetValue()शुद्ध वर्चुअल था, तो प्रोग्राम का व्यवहार अपरिभाषित होता।


संदर्भ: Why a virtual call to a pure virtual function from a constructor is UB and a call to a non-pure virtual function is allowed by the Standard?

+1

आपका उत्तर इतना उपयोगी, स्पष्ट और पूर्ण है। पाठ्यक्रम में आगे जाने से पहले यह समझना मेरे लिए बहुत महत्वपूर्ण था। बहुत बहुत धन्यवाद। अब मैं समझ गया। – Zizou23

2

दूसरे उदाहरण के लिए निम्न कोड का प्रयास करें:

class A 
{ 
private: 
int m_data; 

public: 
A(): m_data(GetValue()) { std::cout << "Init m_data and A ";} 
int Calculate() { return m_data*1.5; } 
virtual int GetValue() { std::cout << "GetValue from A ";return 10; } 
}; 

class B: public A 
{ 
public: 
B() { std::cout << "Init B "; } 
virtual int GetValue() { std::cout << "GetValue from B"; return 20; } 
}; 

int main() 
{ 
B b; A* ap; 
ap=&b; 
std::cout << ap->Calculate() << std::endl; 

return 0; 
} 

यह रूप में आप पहले से ही है, लेकिन आउटपुट के साथ एक ही है। आपको GetValue from A Init m_data and A Init B 15 मिलना चाहिए। मुझे आशा है कि अब आप देखेंगे कि आपके पास 15 का आउटपुट क्यों है। आउटपुट के साथ आप निष्पादन आदेश का पुनर्निर्माण करने में सक्षम होना चाहिए।

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