2011-01-12 11 views
6
struct level0 
{ 
    virtual void foo() = 0; 
}; 

struct level1 : level0 
{ 
    virtual void foo() { cout <<" level1 " << endl; } 
}; 

struct level2 : level1 
{ 
    virtual void foo() { cout <<" level2 " << endl; } 
}; 

struct level3 : level2 
{ 
    using level1::foo; 
}; 

int main() 
{ 
    level1* l1 = new level3; 
    l1->foo(); 
    level3 l3; 
    l3.foo(); 
    return 0; 
} 

ऊपर कोडएक विरासत वर्चुअल फ़ंक्शन को छुपाने के लिए उपयोग की जाने वाली घोषणा-घोषणा है? जीसीसी का उपयोग कर

level2 
level1 

देता है, लेकिन आईसीसी में

level2 
level2 

कौन सा सही है या यह मानक से अपरिभाषित है देता है?

संपादित करें: यह साबित होता है वहाँ निश्चित रूप से एक बग है, निम्नलिखित मुख्य कार्य

int main() 
{ 
    level3 l3; 
    l3.foo();    // This prints level1 

    level3* pl3 = &l3; 
    pl3->foo();    // This prints level2 

    level3& rl3 = l3; 
    rl3.foo();    // This prints level1 

    level3& rpl3 = *pl3; 
    rpl3.foo();    // This prints level2 

    return 0; 
} 

पर विचार तो एक ही वस्तु जब सीधे इस्तेमाल अलग-अलग परिणाम पैदा करता है और जब एक ही प्रकार के एक सूचक के माध्यम से इस्तेमाल किया अलग परिणाम का उत्पादन !!!

+0

मुझे लगता है कि जीसीसी सही है, लेकिन मुझे यकीन नहीं है। –

+0

मजेदार, मैं बस कल इस पर देख रहा था। – aschepler

+0

मैंने टीडीएम मिनजीडब्ल्यू जी ++ 4.4.1 के साथ व्यवहार की पुष्टि की है। यह एक जी ++ बग है, कृपया इसकी रिपोर्ट करें। चीयर्स और एचटी।, –

उत्तर

5

मानक अनुभाग 10.3p2 में एक उदाहरण यह स्पष्ट करता है कि घोषणाओं का उपयोग करके आभासी कार्यों को ओवरराइड नहीं करता है।

यह known g++ bug है।

जैसा कि आपने देखा है, जब किसी सदस्य या संदर्भ के माध्यम से सदस्य फ़ंक्शन को कॉल करते समय, गतिशील प्रकार ज्ञात होता है, तो बग नहीं होता है।

+0

+1। मानक उद्धरण के लिए –

+1

+1, बग के लिए: 2004 में रिपोर्ट किया गया, 2006 में अंतिम अपडेट -> मुझे लगता है कि कोई भी वास्तव में आसान काम नहीं करता है :) –

0

तरह से प्राप्त करने के लिए level1 निश्चित रूप से level1 होगा:

struct level3 : level2 
{ 
    virtual void foo() { level1::foo(); } 
}; 

आपका "का उपयोग" निर्देश संकलक कि यदि आप एक स्तर 3 है और उस पर foo कहते हैं, यह level1 आह्वान चाहिए बताए किया जा रहा है संस्करण, लेकिन यह v-table में इसे ओवरराइट नहीं कर रहा है।

जीसीसी असंगतता के कारण गलत दिखता है, आईसीसी के बारे में निश्चित नहीं है क्योंकि मुझे नहीं पता कि मानक क्या इंगित करता है।

1

using level1::foo;foo फ़ंक्शन level3 कक्षा में प्रस्तुत करता है जो level1::foo को संदर्भित करता है।

सदस्य-घोषणा के रूप में उपयोग की जाने वाली एक घोषणा-घोषणा में, नेस्टेड-नाम-विशिष्टता को कक्षा के आधार वर्ग का नाम दिया जाएगा। इस तरह की एक उपयोग-घोषणा सदस्य नाम लुकअप द्वारा प्राप्त घोषणाओं के सेट को प्रस्तुत करती है।

हालांकि, बाद से level1::foo आभासी है, मुझे लगता है कि यह फोन करके आप level2::foo बुलाना चाहिए, इस प्रकार आईसीसी सही होना चाहिए।

मुझे यकीन नहीं है, वैसे भी।

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

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