2017-07-04 6 views
5

में जावा-जैसे इंटरफेस ओवरलैप करना मैंने कई स्थानों पर पढ़ा है कि जावा के इंटरफ़ेस को सभी शुद्ध आभासी तरीकों के साथ सी ++ के अमूर्त वर्ग का उपयोग करके 100% नकल किया जा सकता है।सी ++

मैं जावा कोड के इस टुकड़े कन्वर्ट करने के लिए कोशिश कर रहा हूँ:

class A { 
public: 
    virtual void a() const = 0; 
protected: 
    virtual ~A() { 
    } 
}; 

class B : public A { 
public: 
    virtual void b() const = 0; 
protected: 
    virtual ~B() { 
    } 
}; 

class C : public /*implements*/ A { 
public: 
    virtual void a() const override { 
    } 
}; 

class D : public /*extends*/ C, public /*implements*/ B { 
public: 
    virtual void b() const override { 
    } 
}; 

D d; 
d.a(); 
d.b(); 

लेकिन कोई बात नहीं कितना मुश्किल मैं कोशिश, मैं हमेशा ऊपर के साथ समाप्त: C++ कुछ इस तरह में

interface A { 
    void a(); 
} 

interface B extends A { 
    void b(); 
} 

class C implements A { 
    public void a() { 
    } 
} 

class D extends C implements B { 
    public void b() { 
    } 
} 

D d = new D(); 
d.a(); 
d.b(); 

सी ++ अस्पष्टता और/या अनुपस्थित शरीर परिभाषाओं के बारे में शिकायत करते हैं।

विचार यह है कि मैं "सी" से प्राप्त करना चाहता हूं जिसमें सभी वर्गों के लिए कुछ साझा कोड शामिल है (यहां: "डी" लेकिन उनमें से अधिक है) और फिर भी वादा बनाए रखें कि "डी" 100% विनिमयशील है किसी भी वर्ग को "बी" लागू करना ("ए" के हिस्सों सहित)।

त्रुटियों मैं ऊपर सी ++ कोड के साथ हो रही है है:

../untitled1/main.cpp: In function ‘int main(int, char**)’: 
../untitled1/main.cpp:39:7: error: cannot declare variable ‘d’ to be of abstract type ‘D’ 
    D d; 
    ^
../untitled1/main.cpp:28:7: note: because the following virtual functions are pure within ‘D’: 
class D : public /*extends*/ C, public /*implements*/ B { 
    ^
../untitled1/main.cpp:7:18: note: virtual void A::a() const 
    virtual void a() const = 0; 
       ^
../untitled1/main.cpp:40:7: error: request for member ‘a’ is ambiguous 
    d.a(); 
    ^
../untitled1/main.cpp:7:18: note: candidates are: virtual void A::a() const 
    virtual void a() const = 0; 
       ^
../untitled1/main.cpp:23:18: note:     virtual void C::a() const 
    virtual void a() const override { 
       ^
+0

क्या आप हमें एक [मिनिमल, *** पूरा *** और सत्यापन योग्य उदाहरण] (http दिखा सकते हैं: // stackoverflow.com/help/mcve), और आपको प्राप्त * वास्तविक * त्रुटियों को शामिल करें (कॉपी-पेस्ट, पूर्ण, पूर्ण और unedited में)? –

+1

@ सोप्रप्रोग्रामड्यूड: कोड स्निपेट * पूर्ण हैं, मुझे लगता है कि मुझे मुख्य() फ़ंक्शन की आपूर्ति करने की आवश्यकता नहीं है। मैंने कंपाइलर आउटपुट जोड़ा है। –

+1

आपको * हीरा समस्या * का सामना करना पड़ सकता है। –

उत्तर

9

यह एक समस्या यह है कि A से आभासी विरासत द्वारा हल किया जाता है।

class A { 
public: 
    virtual void a() const = 0; 
protected: 
    virtual ~A() { 
    } 
}; 

class B : public virtual A { 
public: 
    virtual void b() const = 0; 
protected: 
    virtual ~B() { 
    } 
}; 

class C : public virtual A { 
public: 
    virtual void a() const override { 
    } 
}; 

class D : public C, public B { 
public: 
    virtual void b() const override { 
    } 
}; 

समस्या यह है कि जब तक आप है कि दोनों C और B एक A उप वस्तु (सभी व्युत्पन्न वर्ग उप वस्तुओं के रूप में उनके ठिकानों होते हैं), दो उप वस्तुओं तुम दोनों इनहेरिट से प्राप्त साझा करने की आवश्यकता को निर्दिष्ट B और C असंबद्ध होंगे।

अपने मूल योजना में, A में शुद्ध आभासी सदस्य को C द्वारा प्रदान की कार्यान्वयन एक ही समारोह B में A द्वारा अपेक्षित के लिए एक कार्यान्वयन के रूप में नहीं माना जाता था।

चूंकि अब केवल A उप-ऑब्जेक्ट है, यह समस्या दूर हो गई है। लेकिन ध्यान दें कि वर्चुअल विरासत मूल्य के बिना नहीं है। तो सोचें कि क्या आप वास्तव में ऐसे डिजाइन के साथ जाना चाहते हैं।

+1

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

+0

आपने हीरा की समस्या का समाधान किया – Steephen

+0

@ स्टेफेन - मुझे डरसे मैं इसे हल करने के लिए क्रेडिट के लायक नहीं हूं। यह भाषा डिजाइन समिति थी जो तंत्र के साथ आया :) – StoryTeller

0

सभी आपको क्या चाहिए के कार्यान्वयन है एक() डी वर्ग में:

class A { 
public: 
    virtual void a() const = 0; 
protected: 
    virtual ~A() { 
    } 
}; 

class B : public A { 
public: 
    virtual void b() const = 0; 
protected: 
    virtual ~B() { 
    } 
}; 

class C : public /*implements*/ A { 
public: 
    virtual void a() const override { 
    } 
}; 

class D : public /*extends*/ C, public /*implements*/ B { 
public: 
    void b() const override { 
    } 
    void a() const { 
     C::a(); 
    } 
}; 




int main() 
{ 
    D d; 
    d.a(); 
    d.b(); 
    return 0; 
} 
+1

यह वास्तव में एक वर्ग (सी) में सामान्य कोड साझा करने में मदद नहीं करेगा, क्या यह होगा। कल्पना कीजिए कि आपके पास 20 वर्ग विरासत में हैं जैसे डी। –

+0

तो ऐसा ही कुछ करने के लिए परिवर्तन डी वर्ग की कोशिश: वर्ग डी: सार्वजनिक/* फैली */सी, सार्वजनिक/* लागू करता है */बी { \t सार्वजनिक: \t \t शून्य ख() स्थिरांक ओवरराइड { \t \t} \t \t शून्य() कॉन्स { \t \t \t सी :: ए(); \t \t} \t}; –