अधिभावी पढ़ना this answer, मैं काफी हैरान करता है, तो यह वास्तव में काम करता है अपने आप के लिए बाहर की कोशिश करने का वर्णन किया गया था:अजीब वाक्य रचना जब आभासी कार्यों
#include <iostream>
class A {
public:
virtual void foo() = 0;
};
class B {
public:
virtual void foo() = 0;
};
class C : public A, public B {
public:
virtual void foo();
};
void C::foo(){
std::cout << "C" << std::endl;
}
void C::A::foo(){
std::cout << "A" << std::endl;
}
void C::B::foo(){
std::cout << "B" << std::endl;
}
int main() {
C c;
static_cast<A*>(&c)->foo();
static_cast<B*>(&c)->foo();
c.foo();
return 0;
}
मैं सच में नहीं लगता था कि इसमें से एक आभासी विधि ओवरराइड करने के लिए संभव हो गया था दो अलग-अलग आधार वर्ग, जिनका नाम और हस्ताक्षर है। और, जैसा कि मैंने अपेक्षा की थी, प्रोग्राम प्रिंट के ऊपर:
C
C
C
तो उत्तर गलत है - जैसा कि मैंने शुरुआत से महसूस किया था। आश्चर्यजनक हिस्सा यह है: मेरा जीसीसी इस वाक्यविन्यास को क्यों स्वीकार करता है: void C::A::foo(){
? मुझे इसका मतलब क्या हो सकता है पर कुछ भी नहीं मिला। क्या यह एक जीसीसी बग/फीचर है? क्या यह कुछ अस्पष्ट मानक सी ++ वाक्यविन्यास है? या क्या मैं पूरी तरह से स्थिति की गलत व्याख्या कर रहा हूं?
संपादित करें:
ऐसा लगता है कि void C::A::foo(){}
सिर्फ इस संदर्भ में A::foo
के लिए एक परिभाषा है। पर क्यों? क्या यह जीसीसी बग है? या यह मानक द्वारा किसी भी तरह की अनुमति है? यदि हां, तो क्या यह इस तरह की चीज़, या किसी प्रकार के सामान्य खंड के लिए विशिष्ट नियम है (कहें: यदि कोई पहचानकर्ता समझ में नहीं आता है - जैसे 'सी :: ए :: फू', तो संकलक ऐसा करने के लिए स्वतंत्र है चाहता हे)।
ध्यान दें कि यदि आप 'c.A :: foo()' लिखते हैं तो यह "ए" लिख देगा। –
@ChrisDrew यह वाक्यविन्यास का मतलब है 'foo' के विशिष्ट संस्करण में एक स्थिर (गैर-आभासी) कॉल। मेरे संपादन के साथ, यह स्पष्ट है कि यह "ए" क्यों लिखता है। लेकिन यह किसी भी तरह से 'foo' के लिए वीएमटी प्रविष्टि नहीं बदलता है। –
यह 'ए' का * इंजेक्शन-क्लास-नाम * है, जिसे 'सी' विरासत में मिला है। –