2014-10-03 7 views
41

मैं इस तरह परिभाषित विभिन्न संरचनाओं के साथ कुछ सी ++ कोड प्राप्त किया है:क्या यह सी ++ विनाशक अनावश्यक है?

typedef struct _someStruct_ { 
    std::string someString; 
    std::vector<std::string> someVectorOfStrings; 
    int someOtherStuff; 

    ~_someStruct_() 
    { 
     someString.clear(); 
     someVectorOfStrings.clear(); 
    } 
} someStruct; 

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

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

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

क्या मुझे यहां कुछ याद आ रहा है - क्या कोई कारण है कि स्ट्रिंग और वैक्टर को विनाशक में स्पष्ट रूप से मंजूरी दे दी गई है? मेरा संदेह यह है कि जिसने मुझे यह भेजा है वह वास्तव में एक सी प्रोग्रामर है (सीएफ। टाइपिफ) जिसने कुछ सी कोड को सी ++ में बदलने की कोशिश की है।

+9

हां, यह पूरी तरह से बेकार है। हालांकि यदि वेक्टर कच्चे पॉइंटर्स धारण कर रहे थे तो आपको प्रत्येक पॉइंटर्स पर स्वयं को कॉल करना होगा (जिस बिंदु पर आपको स्मार्ट पॉइंटर्स का उपयोग करना चाहिए)। – Borgleader

+1

जब तक सदस्यों के विनाशकों की आवश्यकता होती है, तो कस्टम विनाशक की कोई आवश्यकता नहीं होती है। –

+14

'typedef _someStruct_ {...} कुछ संरचना; 'पूरी तरह से अनावश्यक भी है, बस' स्ट्रक्चर स्ट्रक्चर {...}; 'लिखें। चूंकि प्रकार एक सी प्रोग्राम में वैध नहीं हो सकता है (क्योंकि यह एक विनाशक का उपयोग करता है) संरचना नाम के लिए टाइपिफ़ का उपयोग करने के लिए कोई कारण नहीं है। –

उत्तर

69

हां, विनाशक पूरी तरह से अनावश्यक है।

जैसा कि आपने स्वयं कहा है कि कोड में अन्य चेतावनियां हैं। उदाहरण के लिए typedef struct का उपयोग करने से सी ++ में कोई भी समझ नहीं आता है, यह खाली विनाशक के रूप में अनावश्यक है: कोड को किसी के द्वारा सी ++ की मामूली समझ के साथ लिखा गया था, और अधिक गठिया होने के लिए बाध्य हैं (एक बात के लिए, कक्षा का नाम अमान्य है वैश्विक दायरे में अग्रणी अंडरस्कोर के लिए)।

+3

रुको, क्या यह एक अग्रणी अंडरस्कोर * नहीं है जिसके बाद एक अपरकेस वर्ण * है? –

+5

@ BartekBanachewicz http://stackoverflow.com/a/228797/981959 –

+0

@ जोनाथन वाकी ओह डान, अब मुझे मिल गया है। मेरी गलती। –

49

वास्तव में, इस बदतर बस निहित नाशक का उपयोग करने से है।

स्पष्ट विनाशक होने के कारण, कंपाइलर आपके लिए एक निहित चालक निर्माता प्रदान नहीं करेगा!

20

विनाशक लगभग पूरी तरह से अनावश्यक है।

यह तीन चीजें करता है।

सबसे पहले, यह प्रतिलिपि/चाल रचनाकारों और असाइनमेंट के स्वचालित निर्माण को अवरुद्ध करता है। यह ... एक अच्छी बात नहीं हो सकती है। लेकिन शायद यह वांछित है। हालांकि, यह वही नहीं है जैसा कि वहां नहीं है।

दूसरा, यह सामान को साफ करने के क्रम को बदलता है। स्ट्रिंग द्वारा धारित बफर को साफ़ कर दिया जाता है, फिर वेक्टर में तारों द्वारा आयोजित प्रत्येक बफर नष्ट हो जाता है, जबकि उन्हें पकड़ने वाली स्ट्रिंग नष्ट हो जाती है, फिर वेक्टर अप्रयुक्त स्मृति का एक बफर नष्ट हो गया है (स्मृति लौट रहा है), तो अब खाली स्ट्रिंग नष्ट हो गई है।

एक डिफ़ॉल्ट नाशक के साथ

, आदेश वेक्टर की स्ट्रिंग के बफ़र्स नष्ट कर रहे हैं, तो वेक्टर के तार के लिए स्मृति, जबकि वेक्टर नष्ट हो जाता है लौटा दिया जाता है, तो स्ट्रिंग अपने बफर लौटाए जाने के साथ-साथ नष्ट हो जाता है है।

आप ऑपरेटर new & delete पर उपयुक्त ओवरलोड के साथ इसका पता लगा सकते हैं, या यदि आपने कस्टम आवंटकों का उपयोग किया है।

आखिरकार, ऐसे विनाशक कभी-कभी डीबग करना आसान हो सकते हैं, क्योंकि आप उनके माध्यम से कदम उठा सकते हैं।

हालांकि, बाधाएं हैं कि इनमें से कोई भी सूक्ष्म प्रभाव नहीं है, जहां डेवलपर द्वारा उस कोड को लिखा गया है।

+0

यह यांत्रिकी के बारे में सोचने के लिए हो सकता है, डिफ़ॉल्ट विनाशक deallocate सकता है लेकिन "scrub" नहीं। असल में मुझे यकीन नहीं है कि मिटाना और साफ़ भी स्पष्ट रूप से अतिरिक्त पदों को शून्य करेगा। हम स्मृति स्केप, यहां तक ​​कि आवंटित स्मृति भी नहीं चाहते हैं। – mckenzm

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