2010-05-25 14 views
5

मैं सामरिक कार्यक्षमता को छोड़कर कुछ कोड को दोबारा करने की कोशिश कर रहा हूं। मुझे किसी ऑब्जेक्ट को बेस इंटरफ़ेस में पॉइंटर कास्टिंग करने में परेशानी हो रही है और फिर बाद में व्युत्पन्न क्लास प्राप्त हो रही है। कार्यक्रम कुछ मामलों में इन वस्तुओं के उदाहरण बनाने के लिए एक फैक्ट्री ऑब्जेक्ट का उपयोग करता है।एकाधिक विरासत वाले वर्ग को नहीं डाला जा सकता

यहां कक्षाओं के कुछ उदाहरण दिए गए हैं जिनके साथ मैं काम कर रहा हूं।

// This is the one I'm working with now that is causing all the trouble. 
// Some, but not all methods in NewAbstract and OldAbstract overlap, so I 
// used virtual inheritance. 
class MyObject : virtual public NewAbstract, virtual public OldAbstract { ... } 

// This is what it looked like before 
class MyObject : public OldAbstract { ... } 

// This is an example of most other classes that use the base interface 
class NormalObject : public ISerializable 

// The two abstract classes. They inherit from the same object. 
class NewAbstract : public ISerializable { ... } 
class OldAbstract : public ISerializable { ... } 

// A factory object used to create instances of ISerializable objects. 
template<class T> class Factory 
{ 
public: 
    ... 
    virtual ISerializable* createObject() const 
    { 
     return static_cast<ISerializable*>(new T()); // current factory code 
    } 
    ... 
} 

This question कास्टिंग के विभिन्न प्रकार क्या करना पर अच्छी जानकारी है, लेकिन यह मदद करने के लिए मुझे इस स्थिति को समझ नहीं है। Static_cast और नियमित कास्टिंग का उपयोग करके मुझे error C2594: 'static_cast': ambiguous conversions from 'MyObject *' to 'ISerializable *' दें। गतिशील_कास्ट का उपयोग न्यूल को वापस करने के लिए createObject() बनाता है। NormalObject शैली कक्षाएं और MyObject का पुराना संस्करण कारखाने में मौजूदा static_cast के साथ काम करता है।

क्या इस कलाकार का काम करने का कोई तरीका है? ऐसा लगता है कि यह संभव होना चाहिए।

उत्तर

10

आपको लगभग आईएसरियलज़ेबल से उत्तराधिकारी है (मैंने अभी इसे वीएस -2010 के साथ परीक्षण किया है)। यह डायमंड समस्या नामक एक आम समस्या है, जहां संकलक को पदानुक्रम पथ लेने के बारे में पता नहीं है।

संपादित करें:

यह करना चाहिए:

class NewAbstract : public virtual ISerializable { ... } 
class OldAbstract : public virtual ISerializable { ... } 
+0

+1: यह भी जीसीसी पर काम किया। – Troubadour

+3

बिल्कुल वही सवाल जो एफएक्यू सिफारिश करता है: http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8 –

+0

यह हल हो गया।मुझे एहसास नहीं था कि सार तत्वों को वस्तुतः प्राप्त करने की आवश्यकता थी। @ मार्क रान्ससम, महान लिंक के लिए धन्यवाद। वह पूरा पृष्ठ बहुत उपयोगी है। –

-2

"डरावना हीरा" और आभासी विरासत देखें। वे आपकी मदद कर सकते हैं।

+0

यदि यह एक लिंक शामिल होता तो मैं इसे +1 देता। –

+2

यहां जवाब किसी विशिष्ट प्रश्न के लिए सटीक उत्तर देने के बारे में नहीं होना चाहिए, लेकिन पोस्टर को उत्तर देने के लिए एक दिशा देने के बारे में देना चाहिए ताकि फिर और जानें और अगली बार इसका उत्तर दे सकें। एक लिंक क्यों प्रदान करते हैं जब इतने सारे लोग उपयोगी हो सकते हैं? शायद इस तरह कुछ: http://tinyurl.com/2cermbg? निर्बाध रूप से अशिष्ट और अनावश्यक लगता है। –

+0

यह बहुत बुरा है कि आप यहां सीधे lmtgfy लिंक पोस्ट नहीं कर सकते हैं। ;) –

0

न्यूएबस्ट्र और ओल्डएबस्ट्र दोनों से वस्तुतः वारिस न करें। वस्तुतः वारिस करने के लिए एक उठाओ। मुझे लगता है कि इसका ख्याल रख सकता है।

+2

उनमें से किसी से भी वस्तुतः उत्तराधिकारी न हो - उन्हें वस्तुतः सामान्य बेस क्लास ('आईएसरियलियाज़ेबल') से प्राप्त होना चाहिए। –

1

आप अपने तत्काल ठिकानों में से एक पहले जैसे कास्ट कर यह दौर मिल सकती है।

virtual ISerializable* createObject() const 
{ 
    NewAbstract*const na = dynamic_cast< NewAbstract* >(new T()); 
    return dynamic_cast< ISerializable* >(na); 
} 
+0

ऐसा लगता है जैसे यह काम कर सकता है। हालांकि मैंने यहां अन्य चीजों से पढ़ा है, ऐसा लगता है कि आपको आधारों के आधार पर इसके साथ वास्तव में सावधान रहना होगा। किसी भी मामले में, इस विशेष मुद्दे के लिए, न्यूएबस्ट्रेट कुछ ऐसा नहीं है जिसे फैक्ट्री ऑब्जेक्ट के बारे में पता होना चाहिए। –

+0

@Jay: हाँ, जब मैंने @ साइमन के जवाब को देखा तो मुझे एहसास हुआ कि यह करने के लिए सही काम था। मुझे इस तथ्य से चूक गया कि आभासी विरासत गलत जगह पर थी। मुझे जवाब देने में कोई फर्क नहीं पड़ता है, भले ही यह बकवास हो, इसलिए मैंने इसे यहां लगी है ...;) – Troubadour

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