2009-02-26 12 views
5

विफल रहता है मेरे पास बेस क्लास और व्युत्पन्न कक्षा है। प्रत्येक वर्ग में एक .h फ़ाइल और एक .cpp फ़ाइल होती है।गतिशील_कास्ट

मैं निम्नलिखित कोड में व्युत्पन्न वर्ग के लिए आधार वर्ग वस्तु के dynamic_cast कर रहा हूँ:

ज फ़ाइलें:

class Base 
{ 
    public: 
    Base(); 
    virtual ~Base(); 
}; 

class Derived : public Base 
{ 
    public: 
    Derived(){}; 
    void foo(); 
}; 

class Another 
{ 
    public: 
    Another(){}; 
    void bar(Base* pointerToBaseObject); 
}; 

cpp फ़ाइलें:

Base::Base() 
{ 
    //do something.... 
} 
Base::~Base() 
{ 
    //do something.... 
} 
void Derived::foo() 
{ 
    Another a; 
    a.bar(this); 
} 
void Another::bar(Base* pointerToBaseObject) 
{ 
    dynamic_cast<Derived*>(pointerToBaseObject) 
} 

कुछ अजीब कारण से , कास्टिंग विफल रहता है (पूर्ण लौटाता है)। हालांकि, कास्टिंग सफल होता है अगर मैं व्युत्पन्न वर्ग के कन्स्ट्रक्टर के कार्यान्वयन को .h से .cpp फ़ाइल में स्थानांतरित करता हूं।

इसका कारण क्या हो सकता है?

कंपाइलर जीसीसी 3.1 है, लिनक्स-एसयूएसई पर। बीटीडब्लू, मैं इस मंच पर केवल इस व्यवहार को देखता हूं, और वही कोड विजुअल स्टूडियो में ठीक काम करता है।

+0

शायद यह जीसीसी 3.1 के साथ एक बग है के साथ ठीक काम करता है? "-फडम्प-क्लास-पदानुक्रम" विकल्प आज़माएं और देखें कि यह आपके दो वर्गों के लिए एक vtable बनाता है –

उत्तर

5

पोस्ट के रूप में, कोड विफल नहीं होना चाहिए, बशर्ते आपके पास बेस क्लास में वर्चुअल फ़ंक्शन हो (जैसा कि litb इंगित किया गया हो)।

लेकिन मेरा मानना ​​है कि प्रत्येक मौजूदा कंपाइलर "बेस क्लास पॉलिमॉर्फिक नहीं है" अगर आपके पास नहीं था, तो शायद यह समस्या नहीं होगी।

एकमात्र चीज जिसे मैं सोच सकता हूं वह यह है कि कुछ अजीब बग के कारण सब कुछ रेखांकित हो जाता है और कोई भी vtable उत्पन्न नहीं होता है। लेकिन अगर आप सी ++ फ़ाइल में कन्स्ट्रक्टर डालते हैं, तो कंपाइलर सब कुछ इनलाइन करने का फैसला नहीं करता है, एक vtable के निर्माण को ट्रिगर करता है, जिससे आपकी कास्ट काम कर सकती है।

लेकिन यह बहुत जंगली अटकलबाजी है, और मुझे नहीं लगता कि किसी भी संकलक उस में इस तरह के एक गलती के लिए होता है (?)

आप एक निश्चित जवाब चाहते हैं, अधिक कोड पोस्ट। और संकलक/मंच का इस्तेमाल किया।

संपादित करें: अद्यतन कोड

मैं आप कम से कम बेस से व्युत्पन्न प्राप्त करना चाहिए लगता है देखकर;) (मुझे लगता है कि लिखने में कोई त्रुटि है)

लेकिन कोड को देखने के बाद, केवल एक चीज मैं के बारे में सोच सकते हैं क्या यह जीसीसी (गलत तरीके से) सब कुछ इनलाइन करता है और व्युत्पन्न के लिए एक vtable उत्पन्न नहीं करता है। इसके लायक होने के लिए, यह जीसीसी 4.0

3.1 अब 7 साल से अधिक पुराना है ... यदि अपग्रेड करने की कोई संभावना है तो मैं इसके लिए जाना चाहूंगा।

7

क्या आपके पास बेस में कोई वर्चुअल फ़ंक्शन है? यह अन्यथा काम नहीं करेगा। यदि कुछ और नहीं है, तो इसके dtor आभासी बनाओ।

पता नहीं है कि यह पहले से ही दूसरे व्यक्ति द्वारा पूछा गया था जिसने अपना जवाब हटा दिया था, लेकिन मेरा मानना ​​है कि यह कुछ अलग था: क्या आप आधार के निर्माता से गतिशील_कास्टिंग कर रहे हैं? यदि ऐसा है, तो यह काम नहीं करेगा। संकलक सोचेंगे कि बेस सबसे व्युत्पन्न प्रकार है, जब आप वर्चुअल फ़ंक्शन को कॉल करते हैं और यह बेस के संस्करण को कॉल करना समाप्त होता है।

+0

मेरे पास बेस में वर्चुअल फ़ंक्शन हैं। –

3

विनाशक वर्चुअल बनाएं, और .cpp फ़ाइल में इसे (या कम से कम एक वर्चुअल विधि) रखें।

कुछ कंपाइलर्स (पढ़ें: जीसीसी) पहले सामना किए गए गैर-इनलाइन वर्चुअल विधि निकाय की तलाश करते हैं और यह निर्धारित करने के लिए इसका उपयोग करते हैं कि वर्चुअल विधि तालिका कहां रखना है।यदि आपके पास .cpp फ़ाइल में निकायों के साथ कोई वर्चुअल विधियां नहीं हैं, तो वर्चुअल विधि तालिका नहीं बनाई गई है।

आपके पास डायनामिक_कास्ट के काम के लिए कम से कम एक वर्चुअल विधि होनी चाहिए। गतिशील कास्ट टाइप जानकारी का पता लगाने के लिए तालिका का उपयोग करता है, और कोई वर्चुअल विधियां नहीं होने पर कोई तालिका नहीं बनाई जाती है।

यदि आपके पास ऐसी कक्षा है जिसे आप उपclassed होने की उम्मीद करते हैं और इसमें एक विनाशक है या यदि वर्ग में कोई इंस्टेंस वेरिएबल्स है जो विनाशकों के साथ कक्षाएं हैं, तो आप वास्तव में अपने विनाशक को वर्चुअल बनाना चाहते हैं (भले ही उसके पास एक खाली शरीर)। अन्यथा आप जिस सफाई की अपेक्षा करते हैं वह सबक्लास उदाहरणों के लिए नहीं होगा।

0

क्या आप इसे Visual C++ में कर रहे हैं? मुझे लगता है कि आप काम करने के लिए कंपाइलर सेटिंग में रनटाइम प्रकार की जानकारी (आरटीटीआई) को सक्षम करना चाहते हैं।

अगर मुझे यह गलत लगता है तो कृपया मुझे दोष न दें। यह थोड़ी देर के बाद से मैंने सी ++ का उपयोग किया है !!!

0

अपना कोड देखने में, मुझे कोई विरासत दिखाई नहीं देती है। क्या आप ऐसा करना भूल गए? व्युत्पन्न कुछ भी नहीं लिया गया है।

0

आपके द्वारा पोस्ट किए गए कोड में डेरिवेट बेस से प्राप्त नहीं हुआ है।

संपादित करें: FYI करें, संशोधित कोड जी ++ 3.4.5

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