2012-05-24 19 views
6

मेरे पास कई कक्षाएं हैं जिन्हें मैंने AngelScript इंजन से कनेक्ट किया है। इस इंजन वस्तुओं आवंटित करने के लिए दिलचस्प तरीके से उपयोग करता है: वस्तु को नष्ट करने केऑब्जेक्ट को कॉल करने के बराबर हटाएं (ऑब्जेक्ट)। ऑब्जेक्ट()

static void Constructor(ObjectType *thisPointer) 
{ 
    new(thisPointer) ObjectType(); 
} 

और इस तरह कोड: यह स्मृति (संभवतः malloc() के साथ) और जब लेखकों इस तरह निर्माण का उपयोग करने के लिए इस स्मृति में वस्तु बनाने के लिए प्रस्ताव की जरूरत राशि आवंटित :

static void Destructor(ObjectType *thisPointer) 
{ 
    thisPointer->~ObjectType(); 
} 

मैं कई प्रश्न हैं:

  • यह नाशक इस तरह से उपयोग करने के लिए सही तरीका है? (ग्रहण इसे एक बग के रूप में न्याय करता है) जहां तक ​​मैं इस कोड को समझ सकता हूं, स्मृति को हटाने के बिना विनाशक को कॉल करना चाहिए (free() पर कॉल करना)
  • क्या इस निर्माण के बजाय delete(thisPointer) (या ऐसा कुछ) का उपयोग करना संभव है और यह होगा बराबर? (कम से कम यह कोड संकलन और रनटाइम के दौरान कोई त्रुटि नहीं देता है)
  • क्या स्मृति को हटाने के बिना विनाशक को कॉल करने के अन्य तरीके हैं?

अग्रिम धन्यवाद।

निर्माण और स्मृति प्रबंधन वास्तव में पूरी तरह से असंबंधित प्रक्रियाओं जो कर रहे हैं सी ++ munges new में एक साथ और सुविधा के लिए delete:

+0

"नियुक्ति हटाने" की खोज के बाद [स्ट्रॉस्ट्रप: सी ++ स्टाइल एंड टेक्निक अकसर किये गए सवाल] (http://www2.research.att.com/~bs/bs_faq2.html#placement-delete) प्रश्न के संक्षिप्त उत्तर के साथ " क्या कोई "प्लेसमेंट डिलीट" है? " - "नहीं, लेकिन अगर आपको एक की जरूरत है तो आप अपना खुद का लिख ​​सकते हैं।" शायद यह किसी की मदद करेगा। –

उत्तर

5

क्या इस तरह विनाशक का उपयोग करने का यह सही तरीका है?

हां।आपने प्लेसमेंट-नई का उपयोग करके ऑब्जेक्ट इन-प्लेस का निर्माण किया है, और इसलिए इसे एक स्पष्ट विनाशक कॉल के साथ नष्ट किया जाना चाहिए (माना जाता है कि इसमें एक गैर-तुच्छ विनाशक है)।

यह इस निर्माण के बजाय delete(thisPointer) (या इसे की तरह कुछ) उपयोग करना संभव है और यह बराबर हो जाएगा?

सं delete मुक्त दुकान में स्मृति को रिहा करने operator delete() का उपयोग करने का प्रयास करेंगे; यह केवल तभी वैध है जब इसे सामान्य new अभिव्यक्ति (या शायद operator new() का स्पष्ट उपयोग) के साथ आवंटित किया गया हो।

क्या स्मृति को हटाने के बिना विनाशक को कॉल करने के अन्य तरीके हैं?

नहीं

वास्तव में। विनाशक को बुलाकर निश्चित रूप से विनाशक को बुलाए जाने का सबसे स्पष्ट और सरल तरीका है।

12

सी ++ एक सा यहाँ भ्रामक है।

हालांकि, सी ++ वास्तव में मौजूदा स्मृति पर एक निर्माता कॉल करने के लिए एक समर्पित वाक्य रचना नहीं है - यह करने के लिए, आप "प्लेसमेंट new" वाक्य रचना जो वास्तव में नहीं है एक पारंपरिक new सब पर उपयोग करने की आवश्यकता - अर्थात् , यह स्मृति आवंटित नहीं करता है।

दूसरी ओर, किसी ऑब्जेक्ट के विनाशक को कॉल करने के लिए एक वाक्यविन्यास है। और आपका कोड सही तरीके से इसका उपयोग करता है। और नहीं, delete का उपयोग करने के बराबर नहीं होगा, यह एक विनाशक को बुलाए जाने के अलावा स्मृति मुक्त करेगा।

std::allocator वर्ग है, जो तरीकों (और उनके इसी अर्थ विज्ञान)

  • allocate (== ::operator new(sizeof T))
  • deallocate (== ::operator delete(&x))
  • construct है के साथ इस की तुलना करें (== new (&x) T())
  • destroy (== x.~T())

ये किसी ऑब्जेक्ट के जीवनकाल चक्र के विभिन्न पहलुओं के अनुरूप हैं।

+0

इसके अलावा, बस इस बिंदु पर जोर देने के लिए: 'ऑपरेटर नया' और 'नया' दो अलग-अलग चीजें हैं, भले ही वे समान दिखते हों। उत्तरार्द्ध (!) पूर्व को कॉल कर सकता है, लेकिन हमेशा नहीं (नियुक्ति-नए संस्करण में)। –

+0

सभी 'नए' अभिव्यक्ति 'ऑपरेटर नई() 'के कुछ ओवरलोड को कॉल करते हैं; नियुक्ति 'नया' कॉल करता है जिसका कोई प्रभाव नहीं पड़ता है। –

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