2012-10-17 14 views
5

सभी विनाशक, ~D(), ~C(), ~B(), ~A() नीचे दिए गए उदाहरण में क्यों बुलाए जा रहे हैं?व्युत्पन्न वर्ग के विनाशक गैर-आभासी होने पर बेस-क्लास विनाशक को व्युत्पन्न वस्तु पर क्यों बुलाया जाता है?

केवल एक आभासी विनाशक है: A का।

#include<iostream> 
using namespace std; 

class A 
{ 
public: 
    virtual ~A() 
    { 
    cout<<"destruct A\n"; 
    } 

}; 
class B:public A 
{ 
public: 
    ~B() 
    { 
    cout<<"destruct B\n"; 
    } 
}; 
class C:public B 
{ 
public: 
    ~C() 
    { 
    cout<<"destruct C\n"; 
    } 
}; 
class D:public C 
{ 
public: 
    ~D() 
    { 
    cout<<"destruct D\n"; 
    } 
}; 

int main() 
{ 
    A* ptr = new D(); 
    delete ptr; 
    return 0; 
} 
+1

क्योंकि भाषा के नियमों का कहना है कि यही होना चाहिए। – juanchopanza

उत्तर

7

एक बार A के नाशक virtual घोषित किया जाता है, सभी व्युत्पन्न वर्ग का विनाशकर्ता, यह भी virtual हैं, भले ही वे स्पष्ट रूप से इस तरह के रूप में घोषित किया नहीं कर रहे हैं .. तो व्यवहार:

यहाँ कोड है जैसा कि आप देख बिल्कुल

+1

@spin_eight एक 'डी' को' ए' 'के माध्यम से एक पॉइंटर के माध्यम से एक्सेस किया जाता है, जिसे डिलीट कहा जाता है। यदि 'ए 'का विनाशक वर्चुअल नहीं था, तो केवल' ~ ए() 'कहा जाएगा। आप आसानी से अपने लिए जांच सकते हैं। – juanchopanza

+0

हां, धन्यवाद! –

6

विनाश क्रम क्या आशा की जाती है है व्युत्पन्न वस्तुओं में बिल्कुल विपरीत निर्माण के क्रम में चला जाता है: पहला सबसेव्युत्पन्न का विनाशकर्ता 10 वर्गों को बुलाया जाता है और फिर आधार वर्गों का विनाशक होता है।

एक विनाशक को वर्चुअल या यहां तक ​​कि शुद्ध वर्चुअल के रूप में परिभाषित किया जा सकता है। यदि आप कभी भी व्युत्पन्न कक्षा बेस क्लास के सूचक के माध्यम से नष्ट होने की अपेक्षा करते हैं तो आप वर्चुअल विनाशक का उपयोग करेंगे। यह है कि यह सुनिश्चित करेंगे सबसे व्युत्पन्न वर्ग का नाशक कहा जाता हो जाएगा:

A* b1 = new B;//if A has a virtual destructor 
delete b1;//invokes B's destructor and then A's 

A* b1 = new B;//if A has no virtual destructor 
    delete b1;//invokes A's destructor ONLY 

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

virtual ~A(); 

REFERENCE

+0

"यहां तक ​​कि शुद्ध आभासी" - रन टाइम त्रुटियों को रोकने के लिए आपको उस विनाशक के लिए आभासी तालिका में पता आवंटित करने के लिए शुद्ध वर्चुअल विनाशक के लिए शरीर बनाना होगा, न केवल nullptr –

0

रूप @juanchopanza कहा - आधार नाशक आभासी साधन घोषित सभी सन्तान आभासी है विनाशकर्ता। यह विरासत योग्यता किसी भी विधियों के लिए है, केवल विनाशकों के लिए नहीं।

यही कारण है कि मैंने उन लोगों से साक्षात्कार किया है जो नहीं जानते थे कि कीवर्ड ने क्या किया क्योंकि उन्हें केवल ढांचे से प्राप्त विधियों को ओवरराइड करना पड़ा था, इसलिए वे सभी वर्चुअल (श्वास) थे।

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