2012-10-23 12 views
5

मैं अपनी पुस्तक में निम्न कोड में देख रहा हूँ:शुद्ध आभासी कार्यों के माध्यम से कक्षा के तत्काल को रोकना?

class Shape 
{ 
    public: 
     Shape(){} 
     ~Shape(){} 
     virtual long getArea() = 0; // Pure virtual function 
     virtual long getPerim() = 0; 
     virtual void draw() = 0; 
}; 

अब यह कहना है कि इन आभासी कार्यों वर्ग सार (जो मैं जावा से समझते हैं), ताकि वर्ग instantiated नहीं किया जा सकता है।

हालांकि, यह कहता है: "कक्षा एक वर्ग में एक या अधिक वर्चुअल फ़ंक्शंस समेत समेकित डेटा प्रकार में है।"

इसका मतलब यह होगा कि अगर मैं एक शुद्ध आभासी समारोह के साथ एक कक्षा की घोषणा की:

class Shape 
{ 
    public: 
     Shape(){} 
     ~Shape(){} 
     virtual long getArea() = 0; // Only pure virtual function 
     virtual long getPerim(){} 
     virtual void draw(){} 
}; 

पूरी कक्षा सार बन जाता है? क्योंकि एक वर्ग 100 + तरीकों है, तो यह हर विधि के लिए =0 लिखने के लिए अगर मैं इसे अमूर्त बाद में बनाने का निर्णय कठिन हो जाएगा।

+0

यदि आप केवल एक शुद्ध समारोह के साथ एक वर्ग का दृष्टांत सकता है क्या होगा, और फिर एक वर्ग 100 + तरीकों, आप कुछ डिजाइन मुद्दों का समाधान करने के लिए है है कि कॉल करने के लिए प्रयास करें ... – PlasmaHH

+2

के बारे में सोचो। – juanchopanza

+0

@juanchopanza लॉल, हाँ, मैं काल्पनिक था। –

उत्तर

11

हाँ, एक एकल शुद्ध virtual विधि वर्ग सार बनाने के लिए पर्याप्त है।

इसके अलावा, आप हमेशा नाशक शुद्ध virtual कर सकते हैं, अगर कोई अन्य तरीकों शुद्ध होने के लिए अनुकूल हैं।

इसके अलावा, आपके नाशक शायद virtual, होना चाहिए, क्योंकि आप स्पष्ट रूप से इस वर्ग से विरासत जा रहे हैं। यह अनिवार्य है यदि आप किसी व्युत्पन्न प्रकार की ऑब्जेक्ट को मूल प्रकार के पॉइंटर के माध्यम से हटाने की योजना बनाते हैं।

+0

मैं अभी भी गैर-शुद्ध कार्यों के भीतर विधियों को डाल सकता हूं, सही? –

+0

@ केन हां वास्तव में। – Lundin

+0

@ केन हाँ ....... –

0

शुद्ध वर्चुअल के रूप में एक विधि घोषित करने का अर्थ है कि आपकी कक्षा के उत्तराधिकारी वर्गों को उस विधि को लागू करना होगा या इसे शुद्ध वर्चुअल छोड़ना होगा, इस स्थिति में व्युत्पन्न कक्षा भी एक अमूर्त वर्ग होगी जिसे तत्काल नहीं किया जा सकता है।

इसके अलावा, जैसा Luchian पहले कहा, आप हमेशा नाशक हर वर्ग कि विरासत में मिला दिया जाएगा के लिए आभासी रूप में घोषित करना चाहिए।

1

आप में है कि एक शुद्ध आभासी विधि वर्ग सार बनाने के लिए पर्याप्त है सही हैं। इसका मतलब है कि आपको एक व्युत्पन्न कक्षा में विधि को लागू करना होगा (व्युत्पन्न वर्ग का)।

मैं अपने "100 + तरीकों के साथ वर्ग" के साथ समस्या है। आमतौर पर यह बहुत खराब डिजाइन का संकेत है।

मैं भी आपके साथ मुद्दों रवैया "थकाऊ हर विधि के लिए 0 लिखने के लिए =" है। सबसे पहले मैं नहीं दिख रहा है कारण है कि यह किसी भी अधिक कठिन लिखना है = 0 की तुलना में यह (और विधि कुछ भी वापस लौट आता है getPerim() करता है, तो आप कुछ नहीं लौटा रही द्वारा अपरिभाषित व्यवहार जोखिम) एक डिफ़ॉल्ट के रूप में {} लिखने के लिए कोई-op कार्यान्वयन है । मुख्य रूप से हालांकि, व्यवसाय तर्क यह निर्धारित करता है कि कोई डिफ़ॉल्ट व्यवहार है या नहीं, बल्कि लेखन का प्रयास नहीं है।

लिस्कोव प्रतिस्थापन सिद्धांत को याद रखें: हालांकि किसी के पास आपकी बेस क्लास का उदाहरण नहीं हो सकता है, लेकिन किसी के पास एक पॉइंटर या संदर्भ होगा, और यह जानने के बिना वर्चुअल विधियों को कॉल करें कि उन्हें वास्तव में कौन सी कक्षा है। (संयोग से लिस्कोव महिला थी, पहला नाम बारबरा था, और 1 9 83 के आसपास कभी-कभी इस सिद्धांत को बताया)।

आपका सार आधार वर्ग लगभग निश्चित रूप से जिस तरह से, एक आभासी नाशक होना चाहिए।

तरीके उस वर्ग के राज्य में परिवर्तन नहीं होगा स्थिरांक घोषित किया जाना चाहिए।

0

एक समारोह शुद्ध सिर्फ वर्ग सार नहीं है अंकन, यह किसी भी व्युत्पन्न वर्ग कि समारोह भी सार पर हावी नहीं होता बनाता है।

इसलिए, यदि आप उन सभी कार्यों को लागू करने व्युत्पन्न वर्ग बाध्य करना चाहते हैं तो उन सब को शुद्ध करते हैं। यदि व्युत्पन्न कक्षा के लिए केवल getArea लागू करने के लिए यह समझ में आता है और अन्य दो नहीं, तो केवल getArea शुद्ध चिह्नित करें। इस उदाहरण में मुझे लगता है कि यह नहीं मेकअप भावना करता है, अगर सब व्युत्पन्न वर्ग जोड़ा गया है क्षेत्र की गणना करने के लिए एक रास्ता है, वहां अभी भी कोई रास्ता नहीं है कि आधार वर्ग परिधि की गणना कर सकता है, क्योंकि।

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