2008-12-09 17 views
44

जावा और सी # वर्गों कि final और sealed खोजशब्दों के साथ आधार वर्ग के रूप में इस्तेमाल नहीं किया जा सकता की धारणा समर्थन करते हैं। C++ में लेकिन वहाँ व्युत्पन्न किया जा रहा है जो एक दुविधा के साथ वर्ग के लेखक पत्ते से से एक वर्ग को रोकने के लिए कोई अच्छा तरीका है, हर वर्ग एक आभासी नाशक नहीं है या करना चाहिए?क्या प्रत्येक वर्ग में आभासी विनाशक होना चाहिए?


संपादित करें: सी ++ के बाद से 11 यह अब सच है, आप निर्दिष्ट कर सकते हैं कि एक वर्ग final है।


एक ओर एक वस्तु एक आभासी नाशक देने पर मतलब है कि यह एक vtable है और इसलिए (64 बिट मशीनों पर या 8) 4 उपभोग vptr के लिए प्रति-वस्तु अतिरिक्त बाइट्स होगा।

दूसरी तरफ यदि कोई व्यक्ति बाद में इस वर्ग से निकलता है और बेस क्लास में पॉइंटर के माध्यम से व्युत्पन्न कक्षा को हटा देता है तो प्रोग्राम खराब परिभाषित होगा (आभासी विनाशक की अनुपस्थिति के कारण), और स्पष्ट रूप से अनुकूलन के लिए सूचक प्रति वस्तु हास्यास्पद है।

gripping hand पर एक आभासी विनाशक (तर्कसंगत) विज्ञापन करता है कि इस प्रकार का उपयोग बहुरूप रूप से किया जाना है।

कुछ लोगों को, आप एक स्पष्ट कारण एक आभासी नाशक का उपयोग नहीं करने की जरूरत है (जैसा कि this question का पहलू है) और दूसरों का कहना है कि केवल जब आप विश्वास है कि अपने वर्ग से प्राप्त किया जा रहा है कारण है कि आप उन्हें का उपयोग करना चाहिए लगता है क्या आप सोचते हैं?

+0

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

+0

डुप्लिकेट्स: http://stackoverflow.com/questions/270917/why-should-i-declare-a-virtual-destructor-for-an-abstract-class-in-c, http://stackoverflow.com/questions/300 9 86/कब-चाहिए-आप-उपयोग-वर्चुअल-विनाशक –

+6

"और प्रति वस्तु सूचक के लिए स्पष्ट रूप से अनुकूलन हास्यास्पद है।" - यह छोटी वस्तुओं के लिए हास्यास्पद नहीं है। सी ++ 0 एक्स एक कंटेनर फॉरवर्डलिस्ट जोड़ रहा है, ठीक है क्योंकि कभी-कभी ऑब्जेक्ट ओवरहेड प्रति पॉइंटर बहुत अधिक होता है - अंतरिक्ष और समय आवश्यकताओं से। –

उत्तर

26

प्रश्न वास्तव में है, क्या आप लागू करना चाहते हैं कि आपके वर्गों का उपयोग कैसे किया जाना चाहिए? क्यूं कर? यदि किसी वर्ग में वर्चुअल विनाशक नहीं है, तो वर्ग का उपयोग करने वाले किसी भी व्यक्ति को पता है कि इसका उद्देश्य नहीं लिया गया है, और यदि आप इसे किसी भी तरह से प्रयास करते हैं तो कौन सी सीमाएं लागू होती हैं। क्या यह पर्याप्त नहीं है?

या अगर आपको कोई अनुमान नहीं था तो पर किसी भी समस्या का सामना करने के लिए आपको कठोर त्रुटि डालने के लिए कंपाइलर की आवश्यकता है?

यदि आप लोगों से इसका अधिग्रहण करना चाहते हैं तो कक्षा को आभासी विनाशक दें। अन्यथा नहीं, और मान लें कि आपके कोड का उपयोग करने वाला कोई भी व्यक्ति आपके कोड का सही उपयोग करने के लिए पर्याप्त बुद्धिमान है।

+6

@jalf: अगर वे इससे निकलते हैं और इसे पॉलिमॉर्फिक तरीके से उपयोग करना चाहते हैं/ – Oszkar

2

मैं "नहीं" सामान्य सवाल का होगा। प्रत्येक कक्षा को एक की आवश्यकता नहीं है। यदि आप जान सकते हैं कि कक्षा को कभी विरासत में नहीं लिया जाना चाहिए, तो नाबालिग उपरांत को लेने की कोई आवश्यकता नहीं है। लेकिन अगर कोई मौका है, तो सुरक्षित पक्ष पर रहें और वहां एक डाल दें।

8

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

+0

तो आप अपने प्रत्येक कोड को कहां उपयोगी करते हैं? शायद कुछ उदाहरण होंगे जहां आपकी कक्षा, जो आपके द्वारा गैर-बहुरूप रूप से उपयोग की जाने वाली है, केवल कुछ विशिष्ट उदाहरणों में बेस क्लास के रूप में उपयोगी है। – v010dya

53

हर सार वर्ग या तो एक होना चाहिए,

  • संरक्षित नाशक, या,
  • आभासी नाशक।

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

नहीं इसे करने के लिए एक सूचक के माध्यम से नष्ट करने के लिए इरादा एक वर्ग के लिए, वहाँ कोई कारण एक आभासी नाशक है। यह न केवल संसाधनों को बर्बाद करेगा, बल्कि अधिक महत्वपूर्ण बात यह है कि यह उपयोगकर्ताओं को गलत संकेत देगा। बस एक क्रांतिकारी भावना के बारे में सोचें जो std::iterator को आभासी विनाशक देने के लिए करेगा।

+2

या से संरचना टीएम, जो पीओडी बंद हो जाएगा और इसलिए अब सी कॉलिंग सम्मेलनों के साथ संगत नहीं होगा। –

+0

महान जवाब, litb। मैं अभी अपने सभी कोड को बदलने जा रहा हूं। –

0

मैं जोड़ देंगे कि कई बार किया गया है जब मैं विनाशकर्ता जब मैं माता-पिता या बच्चे को कक्षा में एक आभासी भूल गया कहा जाता हो रही है नहीं पर थोड़ी देर के लिए मेरे सिर खरोंच है। मुझे लगता है कि मैं अब इसके बारे में जानना जानता हूं।:)

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

4

चेक this article from Herb Sutter:

दिशानिर्देश # 4: एक आधार वर्ग नाशक या तो सार्वजनिक और आभासी, या संरक्षित और nonvirtual होना चाहिए।

+8

ध्यान दें कि वह उन वर्गों के बारे में बात कर रहा है जो * बेस * कक्षाएं हैं, यह प्रश्न विशेष रूप से कक्षाओं के लिए डिज़ाइन नहीं किए गए वर्गों के बारे में है। – Motti

0

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

-3
include<iostream> using namespace std; 

class base { 
    public: base() { 
     cout << "In base class constructor" << endl; 
    } 

    virtual ~base() { 
     cout << "in base class destuctor" << endl; 
    } 
}; 

class derived : public base { 
    public: derived() { 
     cout << "in derived class constructor" << endl; 
    } 

    ~derived() { 
     cout << "in derived class destructor" << endl; 
    } 
}; 

int main() { 
    base *b; // pointer to the base 
    class b = new derived; // creating the derived class object using new 
    keyword; 
    delete b; 
    return 0; 
} 
+0

लड़का मैं अपना उत्तर अनुक्रम में नहीं डाल सका .. – ashutosh

+0

बस अपना कोड पेस्ट करें, इसे चुनें और '{} 'पर क्लिक करें। लेकिन आपने जो पोस्ट किया है वह ऊपर दिए गए प्रश्न का उत्तर नहीं देता है। कोड-केवल उत्तर आमतौर पर यहां पर्याप्त नहीं होते हैं, आपको यह बताने की आवश्यकता है कि आपके द्वारा प्रदान किया गया कोड उत्तर दिए गए प्रश्न का उत्तर क्यों देता है। – Mat

+0

आपने इस प्रश्न का उत्तर नहीं दिया है - बस दिखाया गया है कि यह कैसे करें। – iblamefish

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