2012-01-23 17 views
8
/*Child is inherited from Parent*/ 
class Parent { 
    public: 
    Parent() //Constructor 
    { 
     cout << "\n Parent constructor called\n" << endl; 
    } 
    protected: 
    ~Parent() //Dtor 
    { 
     cout << "\n Parent destructor called\n" << endl; 
    } 
}; 

class Child : public Parent 
{ 
    public: 
    Child() //Ctor 
    { 
     cout << "\nChild constructor called\n" << endl; 
    } 
    ~Child() //dtor 
    { 
     cout << "\nChild destructor called\n" << endl; 
    } 
}; 

int main() 
{ 
    Parent * p2 = new Child;   
    delete p2; 
    return 0; 
} 

यदि मैं Parent के विनाशक वर्चुअल बना देता हूं, तो मुझे एक त्रुटि प्राप्त होती है, तो संरक्षित विनाशक वर्चुअल बनाने का उद्देश्य क्या है?क्या संरक्षित विनाशक वर्चुअल बनाने के लिए कोई उपयोग है?

+1

शायद हमें "डीटीआर संरक्षित क्यों कर देगा?" से शुरू करना चाहिए। –

+4

आप कभी विनाशक वर्चुअल क्यों बनाना चाहते थे? आपको * उद्देश्य * नहीं पता होना चाहिए? एक संरक्षित विनाशक का अर्थ है कि वस्तुओं को बेस पॉइंटर्स के माध्यम से नष्ट नहीं किया जाना चाहिए, इसलिए 'मुख्य' में कोड सादा गलत है। – thiton

+0

देखें http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – user998692

उत्तर

17

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

तो, सबसे पहले आप अपने विनाशक को सुरक्षित रखना चाहते हैं (क्योंकि आप केवल relase के भीतर से वस्तु को नष्ट करना चाहते हैं)।

यदि आप अपनी कक्षा से प्राप्त करने की योजना बना रहे हैं, तो आप भी अपने विनाशक को आभासी बनाना चाहते हैं, क्योंकि जब भी आप किसी क्लास ऑब्जेक्ट को बेस क्लास में पॉइंटर के माध्यम से नष्ट करना चाहते हैं तो आपको आभासी विनाशक की आवश्यकता होती है (धन्यवाद @ शार्पूटोथ संकेत के लिए ...)

+2

नहीं, आपको वर्चुअल विनाशक की आवश्यकता है चाहे व्युत्पन्न कक्षाओं को किसी अतिरिक्त विनाश की आवश्यकता हो, अन्यथा व्यवहार केवल अपरिभाषित है। – sharptooth

+0

@ शार्पतोथ राइट, मैंने इस बारे में नहीं सोचा था। इसे ठीक किया, इसे इंगित करने के लिए धन्यवाद! – MartinStettner

+0

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

4

protected: Base::~Base(); आभासी कम से कम आप अगर (पर योजना) होना चाहिए किसी भी वस्तुओं Base भीतर Base से ली गई या Base की एक व्युत्पन्न वर्ग को हटाने।

+0

इसे हटाएं; किसी भी अज्ञात बच्चे ऑब्जेक्ट के लिए धन्यवाद – tusharfloyd

+0

@ user1085822: तो, आप मेरे उत्तर को अस्वीकार करते समय मुझे धन्यवाद दे रहे हैं। तुम मुझे क्या कहने की कोशिश कर रहे हो? – bitmask

+0

यह नहीं होना चाहिए – ksb

5

हाँ, आप class Parent सदस्य कार्य करता है जो बहुत आम है जब COM ऑब्जेक्ट में IUnknown::Release() को लागू करने में delete this कर करने का इरादा है।

+0

अच्छा। और उस मामले के लिए यदि कोई अन्य पीड़ित वर्ग है, तो 'बहिष्कृत पीबीएएस'; – iammilind

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