2013-08-10 25 views
5

मैं तीन वर्गों इस तरह संरचित है

In function ‘int main()’:
error: request for member ‘GetValue’ is ambiguous
error: candidates are: virtual float Keyword::GetValue()
error: virtual float MeasurementKeyword::GetValue()
error: virtual float CharacterKeyword::GetValue()
फिक्सिंग सी ++ एकाधिक विरासत अस्पष्ट कॉल

:

#include <iostream> 
using namespace std; 

class Keyword 
{ 
    public: 
     virtual float GetValue() = 0; 
}; 

class CharacterKeyword : public Keyword 
{ 
    public: 
     virtual float GetValue(){return _value;} 
    private: 
     float _value; 
}; 

class MeasurementKeyword : public Keyword 
{ 
    public: 
     virtual float GetValue(){return _value;} 
    private: 
     float _value; 
}; 

class AddressType : public CharacterKeyword, public MeasurementKeyword 
{ 

    private: 
     float address; 
     float addresExt; 
}; 

int main() 
{ 
    AddressType *a = new AddressType(); 
    a->GetValue(); 
    return 0; 
} 

मैं निम्नलिखित हो रही है 0

मैंने कई विरासत में कुछ पढ़ा है और मुझे पता है कि इसमें बहुत सारे नुकसान हैं - यह उनमें से एक है। मुझे अपनी कक्षा संरचना इस तरह होने की ज़रूरत है, इसलिए मैं सोच रहा था कि क्या कोई तरीका था कि मैं टेम्पलेट का उपयोग करके इसे ठीक कर सकता हूं?

अद्यतन
अपनी टिप्पणी पढ़ने के बाद, मेरा मूल विचार है कि शायद मैं सिर्फ एक AddressType कि एक CharacterKeyword है और एक AddressType कि AddressType templating द्वारा एक MeasurementKeyword है के बीच चित्रित कर सकते थे। और इसे अद्यतन कोड में उपयोग कर रहा है। या मैं केवल उस सदस्य का नामस्थान निर्दिष्ट कर सकता हूं जिसे मैं चाहूंगा। चूंकि टेम्पलेटेड तरीके का अभी तक एक उत्तर के रूप में उल्लेख नहीं किया गया है, क्या यह एक खराब फिक्स है? क्या मुझे बस उस सदस्य का नामस्थान निर्दिष्ट करना चाहिए जिसे मैं चाहता हूं?

template <class T> 
class AddressType : public T 
{ 

    private: 
     float address; 
     float addresExt; 
}; 

int main() 
{ 
    AddressType<MeasurementKeyword> *a = new AddressType<MeasurementKeyword>(); 
    a->GetValue(); 
    return 0; 
} 
+1

कैसे आप इस .. क्या तुम यहाँ हो करना चाहते हैं ठीक करने के लिए चाहते हैं पर निर्भर करता है? –

+0

@ कार्तिकट इसलिए मैंने उन्हें दोनों तरीकों से दिया;) – aaronman

+0

@ हारोनमैन यूप, आपके समाधान को दोष नहीं दे रहा है, लेकिन यह सुनिश्चित नहीं है कि वह टेम्पलेट्स के साथ क्या करना चाहता है .. –

उत्तर

13

यह एक diamond inheritance pattern की वजह से है, त्रुटि को हल करने के लिए आप विशिष्ट नाम स्थान आप की तरह से सदस्य चाहते हैं निर्दिष्ट कर सकते हैं।

paddressType->MeasurementKeyword::GetValue() 

या

paddressType->CharacterKeyword::GetValue() 

  1. मूल रूप से अपने AddressType वर्ग यह से विरासत और नहीं चुन सकते हैं एक (कॉल अस्पष्ट है) दोनों वर्गों से GetValue सदस्यों के लिए पहुँच नहीं है।
  2. scope resolution operator (::) निर्दिष्ट करता है कि आप वास्तव में कौन सा चाहते हैं।
  3. आपने यह नहीं कहा है कि आप वास्तव में यह कोड क्या करना चाहते हैं, इसलिए मैं कहूंगा कि आम तौर पर जटिल विरासत पैटर्न पठनीय कोड बनाने के लिए अनुकूल नहीं होते हैं, जो वास्तव में आप चाहते हैं पर पुनर्विचार करते हैं।
3

आम तौर पर, जब आप deadly diamond of death में भागते हैं तो यह एक संकेत है कि आपको अपने डिज़ाइन पर पुनर्विचार करना चाहिए। हालांकि, अगर आप पूरी तरह से इस स्थिति से नहीं बच सकते हैं, तो सी ++ virtual inheritance के रूप में एक समाधान प्रदान करता है। आभासी विरासत "हीरा अस्पष्टताओं" में से कुछ को हल करती है, लेकिन यह भी घबराहट है। उदाहरण के लिए, आपको व्युत्पन्न वर्ग 'कन्स्ट्रक्टर में माता-पिता के गैर-डिफ़ॉल्ट कन्स्ट्रक्टर को स्पष्ट रूप से कॉल करना होगा।

एक बार फिर, सबसे अच्छा तरीका हीरा से बचने का सबसे अच्छा तरीका है। मैं कई वर्षों से सी ++ में प्रोग्रामिंग कर रहा हूं, और अब तक मुझे अपने कोड में यह समस्या कभी नहीं मिली है।

+0

है "आपको स्पष्ट रूप से व्युत्पन्न वर्ग 'कन्स्ट्रक्टर में माता-पिता के रचनाकारों को कॉल करना होगा।" आपका मतलब है कि वर्चुअल बेस क्लासेस सबसे अधिक व्युत्पन्न कक्षा में शुरू किए गए हैं? यदि वर्चुअल बेस क्लास में डिफ़ॉल्ट ctors हैं, तो आपको उन्हें स्पष्ट रूप से कॉल करने की आवश्यकता नहीं है। – dyp

+0

वर्चुअल इस समस्या को हल नहीं करता है, कॉल अभी भी संदिग्ध है, मैं बाकी – aaronman

+0

@DyP हां से सहमत हूं। मेरा मतलब है कि आपको माता-पिता की कक्षा का जिक्र करना होगा। – Dima

2

इस तरह AddressType को परिभाषित:

class AddressType : public CharacterKeyword, public MeasurementKeyword 
{ 
public: 
    using MeasurementKeyword::GetValue; 
private: 
    float address; 
    float addresExt; 
}; 
संबंधित मुद्दे