2013-02-25 74 views
7

मैं अब सी ++, OO पक्ष सीख रहा हूँ, और मैं यह सब समय मिल गया:सी ++ अंतर; और खाली समारोह

class SomeClass{ 
    virtual void aMethod()=0; 
} 

class AnotherClass{ 
    void anotherMethod(){/*Empty*/} 
} 

class SomeClassSon : public SomeClass{ 
    void aMethod(){/*Also Empty*/} 
} 

मेरे संदेह नहीं है: क्या 3 विधियों के बीच अंतर है। आभासी शून्य, खाली एक, और आभासी बराबर है, क्योंकि यह विरासत में मिला है, खाली एक।

क्यों मैं सिर्फ पिता की तरह SomeClassSon विधि नहीं बना सकते (आभासी शून्य शून्य के बराबर?)

+0

'कुछ क्लास एस; s.aMethod() 'मान्य कॉल नहीं है। – andre

+3

अंतर वर्ग में '= 0' के साथ अंतर है, प्रत्येक व्युत्पन्न कक्षा * विधि को कार्यान्वित करना चाहिए। –

+2

@ डेविड स्क्ववार्टज़ - यदि कार्य तत्काल * है तो फ़ंक्शन को कार्यान्वित करना चाहिए *। यदि कार्य लागू नहीं किया गया है, तो वर्ग सार है। –

उत्तर

10

अपने

class SomeClass{ 
    virtual void aMethod()=0; 
} 

एक शुद्ध आभासी विधि की उपस्थिति के लिए अपनी कक्षा सार बनाता है। एक बार आपके पास ऐसी एक शुद्ध वर्चुअल विधि हो, =0, आपकी कक्षा में, आप कक्षा को तुरंत चालू नहीं कर सकते हैं। और भी, किसी भी व्युत्पन्न वर्ग को शुद्ध आभासी aMethod() लागू करना होगा, या यह एक सार वर्ग भी बन जाएगा।

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

लेकिन, व्युत्पन्न कक्षा में, विधि का शरीर खाली है, है ना? यही कारण है कि आपका प्रश्न समझ में आता है: क्लास शुद्ध आभासी क्यों नहीं बनाते हैं। खैर, आपकी कक्षा अन्य तरीकों को लागू कर सकती है। यदि ऐसा है, तो SomeClass को तत्काल नहीं किया जा सकता है (एक शुद्ध आभासी विधि है), जबकि बाल वर्ग SomeClassSon हो सकता है।

वही आपके AnotherClass पर लागू होता है, जिसे तत्काल किया जा सकता है, SomeClass के विपरीत।

6

अंतर यह है कि virtual void aMethod() = 0 एक pure virtual function है, जिसका अर्थ है कि है:

  1. SomeClass एक हो जाता है अमूर्त बेस क्लास, जिसका अर्थ है कि इसे तत्काल नहीं किया जा सकता है।
  2. किसी भी वर्ग जो SomeClass से विरासत aMethod को लागू करना चाहिए, या यह भी एक सार आधार वर्ग जो instantiated नहीं किया जा सकता है

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

+1

हो सकता है कि आप सही चीज़ का मतलब हो, लेकिन यह गलत कहता है: 'SomeClass' से प्राप्त कक्षाएं * को * फ़ंक्शन को लागू करने के लिए मजबूर नहीं हैं, लेकिन यदि वे नहीं हैं तो वे सार भी हैं। –

1

एक शुद्ध virtual कक्षा सार बनाता है। एक खाली गैर वर्चुअल विधि कुछ भी नहीं करती है - अगर आप इसे कॉल करने का प्रयास करते हैं तो यह केवल एक लिंकर त्रुटि की ओर जाता है। इसके विपरीत, आप शुद्ध virtual पर कॉल करने का प्रयास नहीं कर सकते (जब तक कि आप इसे किसी कन्स्ट्रक्टर से कॉल करने का प्रयास न करें, जो कि वैसे भी खराब है) क्योंकि संकलक आपको उस ऑब्जेक्ट को बनाने नहीं देगा।

एक तार्किक अंतर भी है - virtual चिह्नित विधि विरासत श्रृंखला के माध्यम से आभासी होगी - अन्य केवल नियमित तरीके हैं।

1

एक शुद्ध वर्चुअल फ़ंक्शन (=0 के साथ आपका पहला उदाहरण) का अर्थ है कि उस कक्षा के किसी ऑब्जेक्ट को तत्काल निकालने के लिए फ़ंक्शन को व्युत्पन्न कक्षा में ओवरराइड किया जाना चाहिए।

दूसरा मूल रूप से केवल एक सदस्य फ़ंक्शन है जो कुछ भी नहीं करता है। चूंकि फ़ंक्शन का एक अलग नाम है और कक्षा SomeClass से संबंधित नहीं है, दोनों एक दूसरे को बिल्कुल प्रभावित नहीं करते हैं।

तीसरा शुद्ध वर्चुअल फ़ंक्शन ओवरराइड करता है, इसलिए SomeClassSon को तुरंत चालू करना संभव है, लेकिन व्युत्पन्न वर्ग में ओवरराइड फ़ंक्शन कुछ भी नहीं करता है।

2

घोषणा एमेथ() = 0 संकलक को बताती है कि यह विधि सबक्लास में प्रदान की जानी चाहिए। कोई सबक्लास जो विधि को लागू नहीं करता है उसे तत्काल नहीं किया जा सकता है। इससे आपको यह सुनिश्चित करने में मदद मिलती है कि बेस क्लास की किसी ऑब्जेक्ट में विधि लागू की जाएगी।

3

"बराबर 0" जिसका आप उल्लेख कर रहे हैं उसे "शुद्ध वर्चुअल" कहा जाता है। यह एक ऐसा कार्य है जिसे बच्चा तत्काल होना चाहता है, आधारभूत कार्यक्षमता प्रदान करने के विरोध में लागू करना है जिसका अर्थ है कि अभिभावक वर्ग उस कार्यक्षमता को परिभाषित करने जा रहा है जो अस्तित्व में है लेकिन माता-पिता को यह नहीं पता कि बच्चा यह कैसे करेगा। ध्यान दें कि यह कक्षा सार को बनाता है कि इसे तत्काल नहीं किया जा सकता है। उदाहरण के लिए, मैं एक "स्तनधारी" वर्ग को परिभाषित करना चाहता हूं जिसे मैं प्राप्त कर सकता हूं और मैं चाहता हूं कि उसके बच्चे एक निश्चित तरीके से कार्य करें - लेकिन मैं बस "स्तनधारी" नहीं बना सकता। इसके बजाय मैं एक "जिराफ" वर्ग बनाउंगा और सुनिश्चित करूँगा कि यह इस तरह की कार्य करता है।

यह SO प्रश्न पर भी समझाया गया है।

"खाली" फ़ंक्शन जिसका आप उल्लेख कर रहे हैं वह कार्यक्षमता है जहां फ़ंक्शन परिभाषित किया गया है और कहा जा सकता है - लेकिन कुछ भी नहीं करता है।