2011-12-12 20 views
32

क्या कोई वर्चुअल विधियों वाला विरासत संभव है? संकलक कह रहा है कि निम्नलिखित कोड polymorphic नहीं है।डाउनकास्ट नहीं कर सकता क्योंकि कक्षा polymorphic नहीं है?

उदाहरण:

Class A(){ 
    int a; 
    int getA(){return a;}; 
} 


Class B(): A(){ 
    int b; 
    int getB(){return b;}; 
} 

अन्य वर्ग हम एक B वस्तु के लिए एक A वस्तु से खिन्न की कोशिश कर रहे हैं:

A *a; 
B *b = dynamic_cast<B*>(a) 

लेकिन यह निम्न त्रुटि देता है:

cannot dynamic_cast ... (source type is polymorphic) 
+1

'ए' एक सूचक नहीं है। क्या यह आपके कोड में है? – littleadv

+0

क्षमा करें, वास्तव में एक सूचक है। – wbarksdale

+0

और त्रुटि संकलन समय या रन टाइम है? यदि रन टाइम, तो आईएमएचओ इसकी अपेक्षित व्यवहार करता है। – littleadv

उत्तर

56

सिंटेक्स त्रुटियों को गैर-सामना करना, आपनहीं कर सकतेएक गैर-बहुलक प्रकार। static_cast वह कास्ट है जिसका उपयोग आप इस मामले में करेंगे, अगर आपको पता है कि यह वास्तव में लक्ष्य प्रकार का एक वस्तु है।

कारण: static_cast मूल रूप से कंपाइलर संकलन समय पर एक जांच करता है "क्या इनपुट आउटपुट में डाला जा सकता है?" इसका उपयोग उन मामलों के लिए किया जा सकता है जहां आप पॉइंटर्स (या संदर्भ) के उत्तराधिकारी पदानुक्रम को ऊपर या नीचे कास्टिंग कर रहे हैं। लेकिन चेक केवल संकलन समय पर है, और संकलक आपको लगता है कि आप क्या कर रहे हैं।

dynamic_cast केवल पॉइंटर या संदर्भ कलाकार के मामले में उपयोग किया जा सकता है, और संकलन समय जांच के अतिरिक्त, यह एक अतिरिक्त रन टाइम जांचता है कि कास्ट कानूनी है। यह आवश्यक है कि प्रश्न में वर्ग में कम से कम 1 आभासी विधि हो, जो इस अतिरिक्त जांच को करने के लिए संकलक (यदि यह आरटीटीआई का समर्थन करता है) की अनुमति देता है। हालांकि, यदि प्रश्न में टाइप में कोई वर्चुअल विधियां नहीं हैं, तो इसका उपयोग नहीं किया जा सकता है।

सबसे आसान मामला, और संभवतः सार्थक यदि आप इस तरह के पॉइंटर्स पास कर रहे हैं, तो बेस क्लास के विनाशक वर्चुअल बनाने पर विचार करना है। गतिशील कलाकारों का उपयोग करने की अनुमति देने के अलावा, यह बेस क्लास पॉइंटर हटा दिए जाने पर उचित विनाशकों को भी बुलाया जा सकता है।

+0

ज्ञान के लिए बहुत बहुत धन्यवाद। वह काम किया। – wbarksdale

2
A a; 
B *b = dynamic_cast<B*>(a) 

यहां एक वस्तु है और बी एक सूचक है।

असल में, सी ++ में दोनों को उतार चढ़ाव और डाउनकास्टिंग की अनुमति है। लेकिन डाउनकास्टिंग का उपयोग करते समय, 2 चीजों पर ध्यान देना चाहिए: 1 सुपरक्लास में कम से कम एक आभासी विधि होनी चाहिए। 2 चूंकि सुपरक्लास उप-वर्ग की तुलना में "छोटा" है, इसलिए किसी को मेमोरी ऑब्जेक्ट का ध्यानपूर्वक उपयोग करना चाहिए।

4

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

यह लेख एक समान उदाहरण बताते हैं: http://www.cplusplus.com/doc/tutorial/typecasting/

+0

डेव ने एक अच्छा जवाब दिया। मुझे उनके पद पर टिप्पणी करने के लिए विशेषाधिकार नहीं हैं। तो, मैं यहां टिप्पणी कर रहा हूं। –

18

आप run-time type information (RTTI) के लिए एक कक्षा में कम से कम एक आभासी विधि सफलतापूर्वक dynamic_cast ऑपरेटर आवेदन करना होगा।

11

बस एक विनाशक वर्चुअल बनाएं (हमेशा किसी भी वर्ग के लिए सुरक्षा के लिए करें)।

+7

किसी भी वर्ग के लिए नहीं बल्कि कक्षा के लिए जो बेस क्लास बनने का इरादा है – ParokshaX