2011-03-19 12 views
7

जब मैं सी ++ में इंटरफ़ेस कक्षाएं लिखते हैं, मैं निम्नलिखित 2 विकल्पों में से किसी का चयनएक अंतरफलक में विनाशकर्ता

class Interface 
{ 
public: 
    virtual R1 f1(p11, p12 , ...) = 0; 
    ... 
    virtual Rn fn(pn1, pn2 , ...) = 0; 
    virtual ~Interface() {} 
} 

या

class Interface 
{ 
public: 
    virtual R1 f1(p11, p12 , ...) = 0; 
    ... 
    virtual Rn fn(pn1, pn2 , ...) = 0; 
    virtual ~Interface() = 0; 
} 
Interface::~Interface() {} 

पहले संस्करण लिखने के लिए कम है के साथ क्या करना है
दूसरा में आकर्षक है इंटरफ़ेस के फ़ंक्शन शुद्ध वर्चुअल

क्या कोई कारण है कि मुझे एक या दूसरी विधि (या शायद एक तिहाई) पसंद करनी चाहिए?
धन्यवाद

उत्तर

5

मैं समझता हूँ के रूप में, आभासी समारोह शुद्ध आभासी करने के उद्देश्य के लिए व्युत्पन्न वर्ग के लिए मजबूर या तो इसके लिए कार्यान्वयन प्रदान करने या स्पष्टDerived::f() में Base::f() लिख कर डिफ़ॉल्ट कार्यान्वयन चयन करने के लिए है।

तो यदि यह सत्य है, तो वर्चुअल विनाशक pure virtual बनाने का उद्देश्य क्या है? क्या यह व्युत्पन्न कक्षाओं को Base::~Base() के लिए कार्यान्वयन प्रदान करने के लिए मजबूर करता है? क्या व्युत्पन्न कक्षाएं Base::~Base() लागू कर सकती हैं? सं।

तो इसका मतलब है कि virtual विनाशक के साथ पहला संस्करण लगभग सभी उद्देश्यों के लिए पर्याप्त लगता है। आखिरकार, आभासी विनाशक का सबसे आम उद्देश्य यह है कि ग्राहक delete प्रकार Base* के पॉइंटर्स के माध्यम से व्युत्पन्न कक्षाओं की वस्तुओं को सही ढंग से delete कर सकते हैं।

हालांकि, अगर आप शुद्ध आभासी नहीं Baseआभासी केवल, में सभी कार्यों बनाने के लिए, और उनके लिए कार्यान्वयन प्रदान (वास्तव में प्रदान करने के लिए है), और एक ही समय में आप Base बनाना चाहते

class Base 
{ 
public: 
    virtual void f() {}; //not pure virtual 
    virtual ~Base() = 0; //pure - makes Base abstract type! 
}; 

Base::~Base() {} //yes, you have to do this as well. 

Base *pBase = new Base(); // error - cannot create instance! 
: सार प्रकार, तो Base में एक शुद्ध आभासी नाशक होने केवल समाधान है

उम्मीद है कि मदद करता है।

1

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

जब तक आपके पास कोई कारण नहीं है कि आप इसे मजबूर क्यों करना चाहते हैं, तो मैं पहले मामले के साथ जाऊंगा।

+2

गलत। दूसरा मामला विनाशक को ओवरराइड करने के लिए बाध्य नहीं करता है: http://ideone.com/aw3kV। इसके अलावा, यह वाक्य * "इसलिए बेस क्लास को विनाशक को लागू करने के लिए मजबूर किया जाता है" * मुझे समझ में नहीं आता है। क्या आप इसे फिर से कर सकते हैं? – Nawaz

+0

@ नवाज़ - क्षमा करें, खराब टाइपो। मेरा मतलब "व्युत्पन्न" था, न कि "आधार"। यह अब तय है। 5:00 बजे कोड लिखना बंद करना होगा। –

2

मेरे लिए, डीटीआर इंटरफ़ेस का हिस्सा नहीं है। फाई() में अन्य भाषाओं में अनुरूप होगा, न कि dtor। इसी तरह, आप फाई() के लिए पूर्व-और बाद की स्थिति लिख सकते हैं, लेकिन डॉटर नहीं। यह सिर्फ एक सी ++ वार्ट बनाता है, और पहली तकनीक इससे निपटने का सबसे आसान तरीका है।

+3

वार्ट या नहीं, सी ++ इंटरफेस का विनाशक हिस्सा बनाता है। चाहे वह आभासी है या यह निर्धारित नहीं करता है कि ग्राहक पॉइंटर-टू-बेस के माध्यम से व्युत्पन्न वर्ग के उदाहरण को 'हटाएं' वैध रूप से हटा सकते हैं या नहीं। वैध ग्राहक क्रिया == इंटरफ़ेस। चाहे वह शुद्ध है या नहीं, बाहरी इंटरफ़ेस का हिस्सा नहीं है, हालांकि, नवाज के अनुसार यह कहता है कि यह एकमात्र शुद्ध कार्य है और इसलिए कक्षा को सार बना देता है। –

+1

मैं सहमत हूं, लेकिन सवाल आभासी बनाम शुद्ध वर्चुअल के बारे में है, वर्चुअल बनाम nonvirtual नहीं। – fizzer

+0

ठीक है, मैंने आपको यह समझने के लिए गलत समझा कि सामान्य रूप से सी ++ में, डीटीआर इंटरफ़ेस का हिस्सा नहीं है। मैं इस सवाल से सहमत हूं, प्रस्तावित विकल्पों के बीच का अंतर इंटरफ़ेस का हिस्सा नहीं है। –

1

ठीक है, एक लिंक मिल गया और इसलिए सोचा कि मैं एक जवाब के रूप में यह उल्लेख होगा:

Are inline virtual functions really a non-sense?

मैं compilers देखा है कि अगर कोई गैर फेंकना नहीं है किसी भी v-तालिका इनलाइन फ़ंक्शन सभी मौजूद हैं (और में शीर्षलेख के बजाय कार्यान्वयन फ़ाइल में परिभाषित किया गया है)। वे त्रुटियों को फेंक देंगे जैसे गायब vtable-for-class-A या कुछ समान है, और आप नरक के रूप में उलझन में होंगे, जैसा कि मैं था।

दरअसल, कि मानक के अनुरूप नहीं है, लेकिन यह इतना शीर्षक में नहीं कम से कम एक आभासी समारोह डाल (यदि केवल आभासी नाशक) पर विचार होता है, ताकि संकलक के लिए एक vtable फेंकना सकता है उस स्थान पर पर कक्षा। मुझे पता है कि यह जीसीसी के कुछ संस्करणों के साथ होता है। (Johannes Schaub) अपने दूसरे मामले से

इसका थोड़ा अलग (वास्तव में इतनी के रूप में करने के लिए जीसीसी समस्या का शिकार गिर नहीं हेडर फाइल पूरी तरह से बाहर समारोह लेने का सुझाव), लेकिन मैंने सोचा कि मैं यह उल्लेख होगा। जीसीसी के क्विर्क कभी-कभी काट सकते हैं।

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