2011-08-26 7 views
16

मुझे निम्न लिंक में वर्णित एक समस्या है जहां एक निजी रूप से विरासत वाली बेस क्लास घोषित करने का प्रयास करते समय "इस संदर्भ में पहुंच योग्य" त्रुटि प्रदान करती है व्युत्पन्न वर्ग के अंदर आधार वर्ग के एक सदस्य: http://bytes.com/topic/c/answers/164246-private-inheritance-renders-class-inaccessibleनिजी विरासत "इस संदर्भ में पहुंच योग्य" त्रुटि वर्ग के साथ बेस क्लास छुपाती है

:: एक्स के साथ स्पष्ट रूप से संदर्भित एक्स उपरोक्त मामले में काम करता है, लेकिन क्या कोड के रूप में एक समारोह में है अगर:

void fooby() 
{ 
    class X {}; 

    class Y : private X {}; 

    class Z : public Y 
    { 
    public: 
     X x; // compiler "inaccessible within this context" error 
    }; 
}; 

कैसे क्या आप इस मामले में एक्स का संदर्भ देते हैं?

अगर फूबी एक संरचना/वर्ग था, तो :: fooby :: एक्स काम करेगा, लेकिन मुझे यकीन नहीं है कि उपर्युक्त मामले में इसे कैसे किया जाए।

+0

आप एक ही प्रकार के सदस्य और बेस क्लास दोनों को करने का प्रयास कर रहे हैं? शायद वह वैकल्पिक सुझाव के साथ मदद करेगा। –

+0

@ मार्क बी - यह व्यवहार को स्पष्ट करने के लिए यह एक साधारण संकलित उदाहरण है जिसे मैं –

उत्तर

10

समस्या यह है कि आप का सामना कर रहे एक इंजेक्शन पहचानकर्ता Y में X (और सभी व्युत्पन्न प्रकार) है कि X को संदर्भित करता है, जो नहीं है है कि वहाँ है वाई

उपयोगकर्ता परिभाषित प्रकार के सामान्य मामले कि नाम स्थान स्तर पर घोषित किया गया है में नीचे सुलभ, आप प्रकार अर्हता प्राप्त करने के नाम स्थान का उपयोग करें और भी पहुंच सकता है:

class X {}; 
class Y : X {}; 
class Z : Y { 
    ::X x;   // or Namespace::X 
}; 

क्योंकि आप की गिरफ्तारी ई एक ऐसे फ़ंक्शन के अंदर अपने प्रकार को परिभाषित करना जो वैध विकल्प नहीं है।

वैकल्पिक रूप से, आप अन्य कामकाज के साथ समस्या के आसपास हो सकते हैं। @Eugene प्रस्तावित रूप में, आप X का उल्लेख करने के लिए एक विकल्प के पहचानकर्ता बना सकते हैं:

typedef class X {} another_name; 
class Y : X {}; 
class Z : Y { 
    another_name x; 
}; 

या आप Y अंदर एक typedef जोड़ने व्युत्पन्न प्रकार के प्रकार प्रदान करने के लिए कर सकते हैं:

class X {}; 
class Y : X { 
public: 
    typedef X X; 
}; 
class Z : Y { 
    X x; 
}; 

यह अंतिम विकल्प काम करता है क्योंकि यह पहचानकर्ता Y के अंदर पहचान करेगा जो public है और इस प्रकार को संदर्भित करता है, इसलिए संकलक को वहां प्रकार मिलेगा और Z में इसका उपयोग करेगा।

+0

+1 को समझने की कोशिश कर रहा हूं और मैंने आज अलग तरीके से 'कक्षा' का उपयोग करने के बारे में सीखा। –

+0

आपका "अगला विकल्प" ("कक्षा एक्स एक्स;") गलत है। यह काम नहीं करेगा - यह वही है और इंजेक्शन वाले क्लास नाम को निजी रूप से विरासत में मिला है और इस प्रकार पहुंच योग्य नहीं है। आप गलत धारणा में प्रतीत होते हैं कि इंजेक्शन क्लास नाम एक प्रकार के बजाय एक वस्तु है। इंजेक्शन क्लास नाम एक वर्ग को संदर्भित करता है और एक प्रकार का नाम है। –

+0

@ जोहान्स: हाँ, आप सही हैं कि उस गलत धारणा थी। मैं वास्तव में इसे मानक में देखने की कोशिश कर रहा था (जी ++ इसे 4.2/4.7 स्वीकार करता है, लेकिन क्लैंग ++ और आओ इसे अस्वीकार कर देता है)। ऐसा लगता है कि 'कक्षा X x;' और 'पहचान दोनों प्रकार = प्रकार 'विफल'। –

9

अच्छा सवाल है, मुझे ऐसा करने का कोई तरीका नहीं मिल रहा है। एकमात्र विकल्प मैं देख रहा हूँ जेड के typedef बाहर शुरू करने के लिए है:

typedef X PITA; 
class Z : public Y 
{ 
public: 
    PITA x; // ok 
}; 
संबंधित मुद्दे