2011-04-09 14 views
7

लेखन कोड के साथ this query के लिए उत्तर खोजने के दौरान, मुझे पता चला कि निजी/संरक्षित विरासत विभिन्न वर्गों से अपवाद प्राप्त करने के तरीके को बदलता है, जो बहुत ही आश्चर्यजनक था। उत्तर खोजने के लिए मैंने पहले मंच प्रश्नों का उल्लेख किया था और मैं this similar question पर आया था।विरासत अपवाद प्रबंधन को प्रभावित क्यों करती है?

मेरे लिए protectedvirtual विधियों के साथ बेस क्लास के लिए विरासत का उपयोग करना काफी स्पष्ट है। मानक को अलग रखते हुए, मैं जानना चाहता था क्यों सी ++ अपवाद हैंडलिंग विरासत विधि कॉल पर विरासत द्वारा प्रतिबंधित है? निम्नलिखित स्निपेट यह बताते हैं:

struct Base { virtual void printError() = 0; }; 
class Derived : protected Base { void printError() { } }; 

int main() 
{ 
try { 
    throw new Derived; 
} 
catch(Base *p) { p->printError(); } // Ideal; but not invoked 
catch(void *p) { ((Base*)p)->printError(); } // Ugly; but only way to invoke 
} 

संपादित करें: अगर हम एक जवाब के रूप में गोपनीयता संबंध पर विचार करें; स्वीकार किए जाते हैं। लेकिन फिर यह केवल catch() बेस पॉइंटर्स प्राप्त करने के लिए क्यों लागू है, जबकि यह बेस पॉइंटर्स प्राप्त करने वाले कार्यों के लिए लागू नहीं है?

+1

+1 अच्छा सवाल है। – Nawaz

+3

मामूली नोट, आपको 'थ्रो' कथन में 'नया' उपयोग करने की आवश्यकता नहीं है, आप केवल ऐसा करके मेमोरी लीक पेश करने का जोखिम उठाते हैं। इसके बजाय 'फेंक दिया गया(); 'और संदर्भ' आधार 'के आधार पर पकड़ें। साथ ही, यह निश्चित रूप से मेरे लिए स्पष्ट नहीं है कि क्यों बेस क्लास वर्चुअल विधियों के लिए 'संरक्षित' विरासत का उपयोग करेगा, मुझे लगता है कि आपको यहां कुछ गड़बड़ है ... और अंत में, अपवाद वर्ग को आम तौर पर 'std :: अपवाद' से प्राप्त होना चाहिए और ओवरलोड 'char const * क्या() const'। –

+0

@Matthieu, धन्यवाद, लेकिन उपरोक्त कोड सिर्फ डेमो उद्देश्य के लिए था। इस मामले में संदर्भ द्वारा पकड़ना संभव नहीं है क्योंकि आप 'शून्य 'नहीं पकड़ सकते हैं; हालांकि मैं संदर्भों को पकड़ना पसंद करता हूं। मेरे डिजाइन के आधार पर, मैं चाहता हूं कि इंटरफ़ेस (यहां 'बेस') कक्षा विधियों (विशेष रूप से वर्चुअल) को अपने किसी भी बच्चे द्वारा अन्य नामस्थानों में नहीं बुलाया जाना चाहिए। – iammilind

उत्तर

10

private के अर्थ में यह नहीं कर सकते बनाता है और protected विरासत यह है कि कक्षा या वर्ग पदानुक्रम के बाहर कोई भी विरासत के बारे में जान सकता है। यह वैसे ही है जैसा वर्ग के बाहर कोई भी निजी सदस्य के बारे में नहीं जान सकता है।
अपनी बेस क्लास द्वारा व्युत्पन्न कक्षा को पकड़ने से पता चला कि व्युत्पन्न वर्ग मूल वर्ग से लिया गया है और विरासत की गोपनीयता का उल्लंघन है।

+0

+1 अच्छा स्पष्टीकरण के साथ अच्छा जवाब! – Nawaz

+0

'पकड़' के दौरान केवल एक समस्या क्यों है; जब एक ही परिदृश्य फ़ंक्शन कॉल पर लागू होता है, तो यह आसानी से स्वीकार्य है! – iammilind

+0

@iammilind, गलत, आप एक समान त्रुटि प्राप्त करते हैं जब आप बेस और तर्क के साथ किसी फ़ंक्शन में निजी रूप से व्युत्पन्न कक्षा का प्रयास करते हैं। अपने लिए यह परीक्षण करें। – shoosh

5

protected विरासत का मतलब केवल Derived है और इसके उप-वर्ग "जानता है" यह भी है- Basemain, और पकड़ बयान, यह "पता नहीं" है। यह एक विशिष्ट पहुंच के साथ विरासत का मुद्दा है।

वर्चुअल प्रेषण इस पर परवाह नहीं करता है - अगर आपके पास वर्चुअल फ़ंक्शन कॉल करने की पहुंच है, तो वर्चुअल प्रेषण उपयोग किया जाता है।

अपने नमूना में, आप एक Derived उपयोग नहीं कर सकते जैसे कि यह एक Base कहीं और main के दायरे में था - तो यह भावना है कि आप या तो catch

+0

+1 अच्छा जवाब। : डी – Nawaz

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