2010-10-15 15 views
10

मान लीजिए मैं इस कोडसी ++ वर्चुअल विनाशक अभी भी आवश्यक है यदि व्युत्पन्न में कोई डेटा सदस्य नहीं है?

class Base{ 
    public: 
     int getVal(); 
    private: 
     int a, b; 
}; 

class Derived::public Base{ 
    public: 
     void printVal(); 
}; 

int main(){ 
    Base *b = new Derived(); 
    delete b;  
} 

मैं एक आभासी नाशक चीज़ें ठीक तरीके से हटाना चाहते हैं पता है, लेकिन यह आधार सूचक के साथ नष्ट करने के लिए (जब वहाँ कोई आभासी नाशक है) बुरा है भले ही कोई आभासी कार्य हैं और कोई व्युत्पन्न कक्षा में डेटा सदस्य? यदि यह किया जाता है तो क्या होगा?

उत्तर

5

आदिम-प्रकार के डेटा के लिए, आपका उदाहरण अभ्यास में सबसे अधिक संभावना है। तथ्य की बात के रूप में, एक vtable उठाने वास्तव में बाधा प्रदर्शन (इसलिए यहाँ कुछ वैध का उपयोग हो सकता है) हो सकता है, लेकिन यह तकनीकी रूप से अपरिभाषित है, 5.3-5.4 प्रति:

हैं के स्थिर प्रकार [ हटाने ऑपरेटर की] संकार्य की गतिशील प्रकार से अलग है, स्थिर प्रकार संकार्य के गतिशील प्रकार का एक आधार वर्ग होगा और स्थिर प्रकार जाएगा एक आभासी नाशक या व्यवहार अपरिभाषित है।

यह वास्तव में सभी अपनी कक्षा में डेटा की "heapness" पर निर्भर करता है, और के रूप में वहाँ कोई ढेर-आवंटित सदस्यों (आपके मामले में) कर रहे हैं, आप ठीक होना चाहिए, लेकिन यह निश्चित रूप से एक कोड गंध है।

+2

धन्यवाद डेविड। – snk

+3

उन चीजों पर भरोसा करना खतरनाक है जो "सबसे अधिक संभावना काम" करेंगे और मान लें कि आपको "ठीक होना चाहिए।" कोड लिखने के लिए यह बहुत बेहतर है कि _will_ काम, तो आप _know_ आप ठीक होंगे। –

+0

जेम्स, मैं यह सुनिश्चित कर दूंगा कि हमेशा एक आभासी विनाशक होता है। यह सिर्फ किसी के द्वारा पूछे जाने वाले एक काल्पनिक है और इसके लिए कोई जवाब नहीं है। दोबारा धन्यवाद। – snk

9

क्या बेस पॉइंटर (जब कोई आभासी विनाशक नहीं है) के साथ हटाना बुरा है, भले ही कोई वर्चुअल फ़ंक्शन नहीं है और व्युत्पन्न कक्षा में कोई डेटा सदस्य नहीं है?

हां।

व्यवहार व्युत्पन्न वर्ग की सामग्री के बावजूद अपरिभाषित है।

यदि यह किया जाता है तो क्या होगा?

कुछ भी हो सकता है।

+1

आपको बहुत बहुत धन्यवाद जेम्स। "कुछ भी हो सकता है" के लिए – snk

+3

+1। कुछ भी! बिल्कुल कुछ भी! :) – ybungalobill

2

व्युत्पन्न वर्ग में आभासी desctructor को व्युत्पन्न विनाशक (polymorphism) को सही ढंग से कॉल करने के लिए आवश्यक है, जब व्युत्पन्न वस्तु बेस क्लास के लिए एक सूचक के माध्यम से बनाई गई है।

उच्च ईमानदारी सीपीपी नियम 3.3.2 आधार वर्गों के लिए 'वर्चुअल' विनाशक लिखें। (क्यूएसीपीपी 2116)

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

class Base {}; 
class Derived : public Base { public: ~Derived() {} }; 

void foo() { 
    Derived* d = new Derived; delete d; // correctly calls derived destructor 
} 
void boo() { 
    Derived* d = new Derived; Base* b = d; delete b; // problem! does not call derived destructor! 
} 
+0

मुझे लगता है कि आपका मतलब है कि आपका विनाशक '~ व्युत्पन्न 'नामित किया जाए, न कि' ~ सी' ... –

+0

@ माइक एलरी, हाँ यही वह है जिसका मैं मतलब चाहता था। मैंने कोड को सही किया है। – ArBR