2012-02-02 10 views
7

मुझे बेस क्लास Base के सभी वंशजों के लिए अंतिम विधि finalize() घोषित करने की आवश्यकता है, जिसे विनाश के दौरान बुलाया जाना चाहिए, और मेरा इरादा ~Base() से शुद्ध virtual void Base::finalize() = 0 पर कॉल करना था, लेकिन सी ++ ऐसी चीज को रोकता है। तो मेरा सवालविनाशक से वर्चुअल विधि को कॉल करना - वर्कअराउंड?

हम वंशजों को सही और प्रारंभिक परिभाषित तरीके से कुछ अंतिम कार्य करने के लिए कैसे उजागर कर सकते हैं?

कोड संकलित नहीं किया जा सकता है कि:

#include <QDebug> 
class Base { 
     public: 
      Base(){} 
      virtual ~Base(){ 
       qDebug("deleting b"); 
       finalize(); 
      } 
      virtual void finalize() = 0; 

    }; 

class A : public Base 
    { 
    public: 
     A(){} 
     ~A(){} 
     void finalize(){qDebug("called finalize in a");} 
    }; 

    int main(int argc, char *argv[]) 
    { 
     Base *b = new A; 
     delete b; 
    } 

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

मैं बच्चे के विनाशक से अंतिम() को कॉल कर सकता हूं लेकिन सवाल यह है कि ऐसा करने के लिए मजबूर होना कैसे है। दूसरे शब्दों में मेरा प्रश्न यह है: क्या उन लोगों को त्यागना संभव है जो बेस क्लास के वंशजों को अंतिम रूप देने के तरीके को लिखने के लिए लिखेंगे, ठीक है, एक दस्तावेज में टिप्पणी करने की तुलना में किसी अन्य तरीके से? :)

उत्तर

7

विनाशक संसाधनों को जारी करने के लिए सही जगह हैं, लेकिन प्रत्येक वर्ग अपने संसाधनों को जारी करने के लिए ज़िम्मेदार है। class A द्वारा अधिग्रहित संसाधनों को class Base द्वारा जारी नहीं किया जाना चाहिए (और बस नहीं)।

आभासी विनाशकर्ता परिभाषित की अनुमति देता है class A के नाशक जब class Base के लिए सूचक को हटाने के लिए एक class A वस्तु की ओर इशारा करते के नाम से जाना

Base* p = new A; 
delete p; // Both A and Base destructors are sequencially called! 

तो उचित संसाधन रिहाई प्राप्त करने के लिए आप बस प्रत्येक वर्ग के जारी करने के लिए है 'में संसाधनों अपने स्वयं विनाशक

+1

ठीक है, मैं इसे देखता हूं, लेकिन मेरा सवाल यह है: क्या उन लोगों को त्यागना संभव है जो बेस क्लास के वंशजों को अंतिम रूप देने के तरीके को लिखने के लिए लिखेंगे, ठीक है, किसी अन्य दस्तावेज में टिप्पणी करने के बजाय? :) –

+1

यह संभव है लेकिन आपको कंपाइलर या रन-टाइम त्रुटियां मिल सकती हैं, क्योंकि उस समय तक 'बेस' के विनाशक को बुलाया जाता है, 'ए' के ​​विनाशक को पहले से ही बुलाया गया है, इसलिए कोई 'ए' ऑब्जेक्ट नहीं है जिस पर अपनी तथाकथित 'अंतिमकरण()' विधि को कॉल करने के लिए। –

+1

मैंने आपके नमूना कोड का उपयोग किया है और 'बेस' के लिए 'अंतिमकरण()' परिभाषित किया है, इस प्रकार इसे सादा वर्चुअल (शुद्ध नहीं) बना रहा है। यह संकलित करता है, लेकिन देखें कि आप इसके निष्पादन से क्या प्राप्त करते हैं http://ideone.com/opDXc –

3

है यही कारण है कि एक आभासी नाशक के लिए है:

class A 
{ 
public: 
    virtual ~A() {} 
}; 

class B : public A 
{ 
public: 
    virtual ~B() {} 
}; 

जब प्रकार B की एक वस्तु एक B या एक A के लिए सूचक के लिए सूचक से चाहे नष्ट हो जाता है, की परवाह किए बिना, दोनों विनाशकर्ता हो जाएगा बुलाया। सबसे पहले, B::~B() और फिर A::~A()

+0

@DmitryKachko बस प्रत्येक विनाशक में 'unsubmit' करने के लिए एक कॉल लिखें जिसमें आप' unsubmit' होने के लिए –

+0

सुनिश्चित करें कि मैं ऐसा कर सकता हूं, लेकिन मैं उन लोगों को स्वीकार नहीं कर सकता जो ए क्लास का आधार –

+0

के रूप में उपयोग करेंगे, आपके लिए धन्यवाद का जवाब! यह मेरी मदद कैसे कर सकता है? मेरे पास शून्य सबमिट नहीं है() फ़ंक्शन जिसे विनाश के दौरान ए के प्रत्येक वंशज में बुलाया जाना चाहिए। Unsubmit का कार्यान्वयन उनमें से प्रत्येक के लिए अलग है। - –

1

बेस क्लास विनाशक को शुद्ध शरीर को एक शरीर के साथ बनाएं, जो आपको वही करना चाहिए जो आप चाहते हैं।

+1

शुद्ध वर्चुअल क्यों? –

+0

व्युत्पन्न कक्षाओं को अपने स्वयं के विनाशक घोषित करने और लागू करने के लिए मजबूर करने के लिए। –

+0

ओह, मैंने नहीं देखा कि आधार सार था (शायद बाद में संपादित)। –

0

बेस के desctructor का उपयोग क्यों नहीं? यह कि विनाशक क्या हैं।

खोज RAII बनाएं और सी ++ में बेहतरीन चीज़ों में से एक को खोजें।

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

+0

आरएआईआई को अपने प्रश्न के साथ क्या करना है? –

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