2012-07-13 18 views
6

मैं एक वर्ग है (यह पल के लिए base कॉल) संरक्षित कंस्ट्रक्टर्स आदि base वापसी मान द्वारा base का एक उदाहरण से कुछ कार्यों सहित एक संरक्षित इंटरफेस, है:दृश्यता मुद्दा

class base { 
protected: 
    base() {} 
    base (base const &other) {} // line 6 
    base foo() { 
     base ret; 
     return ret; 
    } 
}; 

इन कार्यों व्युत्पन्न वर्ग में लिपटे रहे हैं ताकि तरह व्युत्पन्न प्रकार वापस जाने के लिए:

class derived : public base { 
private: 
    derived(base const &b) : base(b) {} 
public: 
    derived() : base() {} 
    derived foo() { 
     derived d(base::foo()); // line 21 
     return d; 
    } 
}; 

एकमें base वापसी प्रकार से रूपांतरण सुविधाजनक बनाने के लिएरिटर्न टाइप, मैं derived में एक निजी कन्स्ट्रक्टर प्रदान करता हूं जो इसे संभालता है। ,, के अलावा

test.cpp: In member function ‘derived derived::foo()’: 
test.cpp:6: error: ‘base::base(const base&)’ is protected 
test.cpp:21: error: within this context 

जीसीसी 4.6.1 और बजना 2.9 लिनक्स टकसाल 12 पर के साथ, कोड फ़ाइल संकलित भी -Wall -Wextra साथ:

जीसीसी 4.1.2 के साथ Centos 5.8 पर इस संकलन निम्न त्रुटि पैदा करता है unused parameterbase की कॉपी कन्स्ट्रक्टर के लिए चेतावनी।

मुझे लगता है कि यह जीसीसी 4.1.2 में एक कंपाइलर बग हो सकता है, लेकिन मैं नेट पर कुछ भी नहीं ढूंढ पाया। क्या किसी ने इसे पहले कभी देखा है?

मैं बड़े पैमाने पर बिना संक्रामक संकलक को अद्यतन नहीं कर सकता। क्या बेस क्लास सार्वजनिक की कॉपी कन्स्ट्रक्टर बनाने के अलावा कोई आसान कामकाज है?


संपादित मैं derived::foo() में लाइन 21 से पहले base b; गयी। उस स्थिति में, जीसीसी 4.6.1 और जीसीसी 4.1.2 शिकायत करते हैं कि base का डिफ़ॉल्ट सीटीआर संरक्षित है, चेतावनी के बिना 2.9 संकलित है। डेविड रोड्रिगुएज़ - ड्रबीस ने अपनी टिप्पणी में कहा - डिफ़ॉल्ट सीटीआर base के एक अलग उदाहरण पर नहीं कहा जा सकता है।


संपादित 2 मानक पैरा कि यहाँ लागू करने के लिए लगता है 11.5 [class.protected] है। जीसीसी 4.1.2 मेरे कोड को गलत के रूप में अस्वीकार करने में सही लगता है और मुझे आश्चर्य है कि जीसीसी 4.6.1 और क्लैंग इसे क्यों अनुमति देते हैं। प्रारंभिक समाधान के लिए अपना स्वयं का जवाब देखें।

+0

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

+0

हाँ, मैंने इसके बारे में पढ़ा भी (इसे मानक में भी देखा), और यह मेरा पहला विचार भी था, लेकिन मुझे आश्चर्य है कि क्यों दोनों जीसीसी 4.6.1 और clang 2.9। समस्याओं के बिना इसे संकलित करें। – arne

+0

+1 @ डेविडरोड्रिगुएज़-ड्राईबीस आंख खोलने। मैं इस पूरे समय गलत इंप्रेशन के तहत रहा हूं। इतना ही नहीं, मैं सटीक विपरीत ** ** ** ** था। –

उत्तर

0

मेरे प्रारंभिक समाधान बनाने के लिए base के public ctor नकल है। base की प्रतिलिपि ctor का उपयोग करते हुए derived उदाहरणों की प्रतिलिपि को अस्वीकार करने के लिए, public के बजाय विरासत protected होने की आवश्यकता है। परिणामी कक्षाएं अब इस तरह दिखती हैं:

class base { 
protected: 
    base() {} 
public: 
    base (base const &other) {} 
protected: 
    base foo() { 
     base ret; 
     return ret; 
    } 
}; 

class derived : protected base { 
private: 
    derived(base const &b) : base(b) {} 
public: 
    derived() : base() {} 
    derived foo() { 
     derived d(base::foo()); 
     return d; 
    } 
}; 
1

का संभावित हल है कि आप उस निर्माण करती है यह आधार कार्यप्रणाली को कॉल करके आधार है व्युत्पन्न के लिए एक निजी निर्माता बनाने शामिल होगा की कोशिश कर सकते:

class derived : base { 
    struct from_base_foo {}; 
    derived(from_base_foo) : base(base::foo()) {} 
public; 
    derived foo() { 
     return derived(from_base_foo()); 
    } 
}; 
+0

इसे आजमाया गया, फिर त्रुटि को आपके नए '' बेस 'कन्स्ट्रक्टर को कॉल के लिए उत्सर्जित किया गया है। 'व्युत्पन्न' कन्स्ट्रक्टर। – arne

+0

ओह, ठीक है यह प्रारंभिक सूची में शिकायत कर रहा है, जबकि आधार 'आधार :: foo' को आधारभूत प्रतिलिपि के लिए तर्क के रूप में पारित किया गया है ... –

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