2011-08-12 6 views
5
class Base 
{ 
    virtual void foo() = 0; 
    //~Base();  <-- No destructor! 
}; 

जाहिर है, Base व्युत्पन्न किया जाएगा। तो, क्या सी ++ कहता है कि Base का कंपाइलर-जनरेटेड विनाशक वर्चुअल होना चाहिए?क्या एक सार आधार वर्ग का संकलक-उत्पन्न विनाशकारी आभासी होगा?

धन्यवाद!

+3

नहीं, लेकिन मैं आपको मानक के लिए संदर्भ नहीं दे सकता * कहता हूं ... –

+2

यदि केवल कंपाइलर स्टैक ओवरफ्लो पर प्रश्नों का उत्तर दे सकते हैं;) – MerickOWA

उत्तर

6

नहीं, विनाशक virtual नहीं होगा जबतक कि आप इसे इस तरह चिह्नित न करें। कारण सरल है - कॉल पॉइंटर्स के माध्यम से और संदर्भों के माध्यम से वस्तुतः दोनों को बनाया जा सकता है और आप कॉल कैसे करते हैं और चाहे आप वर्चुअल रूप से new के साथ ऑब्जेक्ट बनाते हैं। यदि आप new के साथ ऑब्जेक्ट्स नहीं बनाते हैं तो आपको delete नहीं है और इसलिए आपको वर्चुअल विनाशकों की आवश्यकता नहीं है।

1

नहीं, डीटीआर वर्चुअल होने की गारंटी नहीं है।

विशेष रूप से वर्चुअल डॉटोर घोषित करने के लिए विशेष रूप से तैयार किए जाने वाले वर्गों की घोषणा करते समय कक्षाओं की घोषणा करते समय। यह आम तौर पर एक बिल्कुल सही डिजाइन दोष नहीं है। असल में, मैं ऐसे मामले के बारे में नहीं सोच सकता जहां यह बेस क्लास से वर्चुअल डॉटर को छोड़ने के लिए डिज़ाइन दोष नहीं है।

+2

कुछ वर्गों को से प्राप्त करने के लिए डिज़ाइन किया जा सकता है लेकिन नहीं बहुरूप रूप से प्रयोग किया जाता है (उदाहरण के लिए, 'बूस्ट :: noncopyable')। इस मामले में, आभासी विनाशक प्रदान करने में कोई बात नहीं है। –

+0

@ ल्यूक: उस स्थिति में, अमान्य बहुलक विलोपन को रोकने के लिए, बेस क्लास विनाशक को संरक्षित करना एक अच्छा विचार है। –

+0

वैसे यह सच है। मैं प्रश्न के संदर्भ के संदर्भ में सोच रहा था, जो एक एबीसी था। –

2

ऐसा नहीं है। यह एक सबूत है कि नाशक स्वचालित रूप से आभासी नहीं किया जाता है के करीब है:

#include <iostream> 

struct BaseBase { 
    ~BaseBase() { 
     std::cout << "~BaseBase\n"; 
    } 
}; 

struct Base : BaseBase 
{ 
    virtual void foo() = 0; 
    //~Base();  <-- No destructor! 
}; 

struct Derived : Base { 
    void foo() { std::cout << "foo\n"; } 
    ~Derived() { 
     std::cout << "~Derived\n"; 
    } 
}; 

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

इस कार्यक्रम वास्तव में अपरिभाषित है व्यवहार है, लेकिन मैं दृढ़ता से संदेह है कि आपके कार्यान्वयन पर इसे प्रिंट नहीं है "~ व्युत्पन्न" । यदि Base में वर्चुअल विनाशक था, तो उसके पास अपरिभाषित व्यवहार नहीं होगा, और यह "~ व्युत्पन्न" प्रिंट करेगा।

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

+0

मैंने कोडपैड में परीक्षण किया: http://codepad.org/oMs4Kuye (g ++ 4.1.2) और यह आपके द्वारा अपेक्षित "~ व्युत्पन्न" प्रिंट नहीं करता है। न तो मेरे एमएसवीसी 2008 पर। उदाहरण के लिए धन्यवाद। –

1

नहीं। कक्षा में वर्चुअल सदस्य हो सकते हैं, इसे प्राप्त किया जा सकता है और new के साथ भी आवंटित किया जा सकता है और वर्चुअल विनाशक के बिना delete के साथ हटा दिया जा सकता है।

क्या अवैध (यूबी) है क्या करना delete आधार पर अगर नाशक आभासी घोषित नहीं किया गया है एक सूचक का उपयोग कर के साथ एक व्युत्पन्न उदाहरण नष्ट करने के लिए है।

बेशक कोई वर्चुअल विनाशक घोषित करने के लिए कोई कारण नहीं है यदि आपकी कक्षा का व्युत्पन्न होना है।

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