2009-09-24 20 views
9

क्या error C2243 से छुटकारा पाना संभव है?त्रुटि से छुटकारा पाएं C2243

class B {}; 
class D : protected B {}; 

D d; 
B *p = &d; // conversion from 'D *' to 'B &' exists, but is inaccessible 

मैं अपने अनुप्रयोग में इस त्रुटि था और अंत में मैं एक स्पष्ट रूपांतरण करके इसे संकलित करने के लिए प्रबंधित किया है: क्यों विरासत में मिला संरक्षित वर्ग डी बनाकर

D d; 
B *p = (B*)&d; 

मैं नहीं समझ सकता बी से अंतर्निहित रूपांतरण अप्राप्य बनाता है।

मैं कक्षा डी में एक ऑपरेटर बी() बनाने के क्रम में रूपांतरण सुलभ बनाने के लिए द्वारा स्पष्ट रूपांतरण से बचने के लिए करने की कोशिश की:

class B {}; 
class D : protected B 
{ 
public: 
operator B() {return *this;} 
}; 

लेकिन वहाँ कोई रास्ता नहीं है।

स्पष्ट रूपांतरण से बचने के लिए कोई अन्य समाधान?

उत्तर

17

यदि आप रूपांतरण की अनुमति देना चाहते हैं, तो आपको सार्वजनिक विरासत का उपयोग करना चाहिए।

संरक्षित या निजी विरासत का उपयोग करके, आप यह घोषणा कर रहे हैं कि आधार वर्ग से प्राप्त व्युत्पन्न प्रकार एक विवरण है जो बाहर से दिखाई नहीं दे रहा है: यही कारण है कि आपको वह त्रुटि मिल रही है।

आपको विधियों को ओवरराइड करने की अतिरिक्त संभावना के साथ संयोजन के रूप में गैर-सार्वजनिक विरासत केवल पर विचार करना चाहिए।

+0

के बारे में केवल का उपयोग करने देने के लिए क्या बेस क्लास का कॉन्स इंटरफेस? तो निजी तौर पर विरासत में और आधार बनाने के लिए कास्ट करने की इजाजत दी? पूछना क्योंकि यह एमएसवीसी पर काम नहीं कर सकता ... –

+0

बस मुझे जवाब दे रहा है, आपको कक्षा को विरासत में विरासत से संभालने की आवश्यकता नहीं है, अन्यथा एमएसवीसी भ्रमित हो जाता है और निजी विरासत (छुपा कलाकार ऑपरेटर छुपा) –

8

क्योंकि protected और private विरासत is-a संबंध नहीं हैं, वे रचना के लिए सिंटैक्स चीनी हैं। अपनी कक्षाओं वास्तव में इस तरह लिखा जा सकता है, लेकिन आप संकलक दे की सुविधा खो आप के लिए b परिभाषित करते हैं, और ख के सदस्यों का उपयोग कर के बजाय सीधे स्पष्ट रूप से इसे की चर्चा करते हुए: के दूसरे बिंदु के लिए

class D 
{ 
    protected: 
    B b; 
}; 

अपने प्रश्न:

operator B() {return *this;} 

इस लाइन B और D से कोई लेना देना नहीं है। डी * और बी * बी और डी से बिल्कुल अलग हैं हालांकि वे उनके लिए संकेतक हैं! संकेत कास्ट करने के लिए, आप सूचक पुनर्व्याख्या सकता है:

B *p = reinterpret_cast<B*>(&d); // TOTALLY WRONG, although it compiles :) 

ऊपर लाइन मत करो! मुझे लगता है कि आप हमें जो कुछ हासिल करने की कोशिश कर रहे हैं, उससे हमें अधिक जानकारी दे सकते हैं।

2

क्योंकि डी और डीएस बच्चों में से कोई भी नहीं जानता कि वे माता-पिता हैं, इसलिए आपको इसे स्पष्ट रूप से करने की आवश्यकता है।

क्या विरासत विरासत का मतलब है, केवल आपके परिवार (बच्चों) को पता चलेगा कि आप विरासत में हैं। और आप इसका इस्तेमाल कर सकते हैं, उदाहरण के लिए बच्चों की विधि में, एक निहित रूपांतरण कानूनी होगा।

यदि आप अपने बच्चों से निहित रूपांतरण करना चाहते हैं तो आपको इसे सभी को जानने के लिए इसे सार्वजनिक करने की आवश्यकता है।

0

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

फिर भी, संरक्षित बी विरासत का मतलब है कि आप बी * पी = & डी को रोकने से रोकने का इरादा रखते हैं। कल्पना करें कि बी वास्तव में डी के शीर्ष पर एक संरक्षित सदस्य चर था। जैसे कि आप उस मामले में डी.बी. तक नहीं पहुंच सकते हैं, आप बी * के रूप में डी तक नहीं पहुंच सकते हैं, जब तक कि आप इसे दूर नहीं करते।

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

+1

ऑपरेटर बी बनाने के द्वारा रूपांतरण को हल करने का प्रयास करता है।() सार्वजनिक या तो काम नहीं करता है –

2

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

पुरानी सी शैली कास्ट जिसे आप उपयोग कर रहे हैं, में नए सी ++ कास्ट्स में से कोई भी सूक्ष्मता नहीं है, इसलिए यह आपको संकलित करेगा जो कोड संकलित करेगा लेकिन समस्या वास्तव में विरासत में है।

0

क्योंकि कोई भी नहीं जानता है बाहर वे अभिभावक-बच्चे हैं, तो आप केवल एक उदाहरण (विजुअल स्टूडियो 2013 में टेस्ट) है D के व्युत्पन्न class.This में इस क्रिया को निष्पादित कर सकते हैं:

class BASE{}; 

class BASE1 :protected BASE{}; 

class BASE2 :protected BASE1 
{ 
public: 
    void func(BASE &a, BASE1 &b){a = b;} 
}; 

void main() 
{ 
    BASE a; 
    BASE1 b; 
    BASE2 c; 

    c.func(a, b);; 
    system("pause"); 
}