2010-07-26 24 views
8

पर आभासी desctructor मैंशुद्ध सार आधार वर्ग

struct IMyInterface 
{ 
    virtual method1() = 0; 
    virtual method2() = 0; 
}; 

जीसीसी का कहना है कि मैं

struct IMyInterface 
{ 
    virtual method1() = 0; 
    virtual method2() = 0; 
    virtual ~IMyInterface(){}; 
}; 

मैं देख रहा हूँ क्यों न होता है। इंटरफ़ेस (डुह) के बारे में एक शुद्ध इंटरफ़ेस है। विनाशक इंटरफ़ेस के ठोस कार्यान्वयन के आंतरिक कार्यान्वयन विवरण का हिस्सा है; यह इंटरफ़ेस का हिस्सा नहीं बनता है। मैं पूरी स्लाइसिंग समस्या को समझता हूं (या कम से कम मुझे लगता है कि मैं करता हूं)

तो मेरा सवाल यह है कि - क्या जीसीसी इस पर जोर देने का अधिकार है और यदि ऐसा है तो क्यों?

+0

आप विनाशकों के बारे में बात कर रहे हैं, लेकिन आपका कोड एक निर्माता दिखाता है। किस बारे में सवाल है? –

+0

@mmyers, इसे ठीक किया गया। प्रोग्रामिंग के –

+1

नियम 1: कंपाइलर हमेशा सही है। प्रोग्रामिंग का नियम 2: यदि कंपाइलर गलत है, नियम 1 लागू होता है। –

उत्तर

19

सी ++ spec के अनुसार, हाँ।

आप वर्चुअल क्योंकि अन्यथा नाशक घोषित करने के लिए, बाद में जरूरत

IMyInterface * ptr = getARealOne(); 
    delete ptr; 

व्युत्पन्न वर्ग पर नाशक फोन नहीं है (क्योंकि नाशक vtable में नहीं है)

यह करने की जरूरत है गैर-शुद्ध रहें क्योंकि बेस क्लास विनाशकों को हमेशा उप-वर्ग विनाशक द्वारा बुलाया जाता है।

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

+4

नाइटपिक - मुझे लगता है कि यदि आप इसे लागू करने के लिए बाल कक्षाओं की आवश्यकता चाहते हैं तो आप इसे शुद्ध आभासी बना सकते हैं। लेकिन आपको अभी भी बताए गए कारणों के लिए एक कार्यान्वयन प्रदान करना होगा। –

+0

मुझे ऐसा नहीं लगता - इसे कहा जाएगा, इसलिए बेहतर परिभाषा है। मैंने इसे आजमाया नहीं है, लेकिन आम तौर पर एक शुद्ध वर्चुअल को संकलक द्वारा कार्यान्वित किया जाता है क्योंकि वीटीबल में एक त्रुटि फ़ंक्शन डालने के लिए शिकायत की जाती है। शायद मैं विनाशकों के लिए एक विशेष मामला कल्पना कर सकता हूं, लेकिन मुझे पूरा यकीन है कि यह नहीं है कि कल्पना क्या है (हालांकि 100% नहीं) –

+0

@Lou फ्रैंको: शुद्ध वर्चुअल फ़ंक्शंस में परिभाषाएं हो सकती हैं। –

3

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

struct A { 

    virtual ~A() {} 

}; 

struct B : A { 

    std::string us_constitution; 
}; 


B* pb = new B(); 
A* pa = pb; 

delete pa; // without the virtual d'tor in the base class, 'B::us_constitution' would never be freed. 
+0

नाइटपिक: बी :: us_constitution को मुक्त नहीं किया जा सकता क्योंकि यह कभी नया नहीं था। हालांकि, इसका उपयोग करने वाले भंडारण को वर्चुअल विनाशक के बिना सिस्टम में वापस नहीं किया जाएगा। –

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