2010-11-10 17 views
15

मैं इस तरह कोड देखा:क्यों कॉल ऑपरेटर नई स्पष्ट

void *NewElts = operator new(NewCapacityInBytes); 

और मिलान कॉल स्पष्ट रूप operator delete प्रयोग किया जाता है फलस्वरूप बाद में।

के बजाय ऐसा क्यों:

void *NewElts = new char[NewCapacityInBytes]; 

क्यों operator new और operator delete को स्पष्ट कॉल ??

+1

क्या आपने उद्देश्य पर दूसरे उदाहरण पर स्क्वायर ब्रैकेट लगाए थे? –

+0

शायद इरादा: 'नया चार [न्यू कैपेसिटी इनबाइट्स]' – MSalters

+0

@MSalters: आप सही हैं, – zaharpopov

उत्तर

24

स्पष्ट रूप से operator new पर कॉल करना जो वैश्विक "कच्चे" ऑपरेटर को नए कहते हैं। ग्लोबल operator new ऑब्जेक्ट के कन्स्ट्रक्टर या new के किसी भी उपयोगकर्ता द्वारा परिभाषित ओवरलोड को कॉल किए बिना कच्चे मेमोरी ब्लॉक देता है। तो बुनियादी तौर पर, वैश्विक operator new समान malloc को सी

से

तो है:

// Allocates space for a T, and calls T's constructor, 
// or calls a user-defined overload of new. 
// 
T* v = new T; 

// Allocates space for N instances of T, and calls T's 
// constructor on each, or calls a user-defined overload 
// of new[] 
// 
T* v = new T[N]; 

// Simply returns a raw byte array of `sizeof(T)` bytes. 
// No constructor is invoked. 
// 
void* v = ::operator new(sizeof(T)); 
+2

यह उपयोगी कब है? – zaharpopov

+6

@zaharpopov: एक उदाहरण एक मेमोरी पूल को कार्यान्वित करेगा जहां आप एक बार एक बड़ा हिस्सा आवंटित करेंगे और पूल के उपयोगकर्ता 'नए' का उपयोग करने के बजाय, खंडों के भीतर वस्तुओं को बनाने वाले कार्यों को कॉल करेंगे। आवंटन पैटर्न के आधार पर, यह 'नया' और 'हटाएं' से बेहतर प्रदर्शन प्रदान कर सकता है। –

+0

ओउ। दिलचस्प। मुझे सी ++ के * इस * कोने के बारे में पता नहीं था। –

2

आप ऑपरेटर नई (bytesize) कहते हैं, तो आप यह करने, हटाने का उपयोग कर नष्ट कर सकते हैं, जबकि अगर आप के माध्यम से नए चार [आवंटित बाइटसाइट], तो आपको इसे हटाएं [] का उपयोग करके मिलान करना होगा, जहां कहीं भी संभव हो से बचने के लिए घृणा है। यह संभवतः इसका उपयोग करने का मूल कारण है।

+1

यह घृणा कैसे है? –

+3

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

+0

@ चार्ल्स: उन्होंने कुछ भी नया स्थान नहीं लगाया, और उस स्मृति को विनाश की आवश्यकता नहीं है। पूरी तरह स्मृति आवंटित करने के रूप में, तो ऑपरेटर नया() सबसे सुरक्षित शर्त है क्योंकि इसे हटाने के लिए [] या असामान्य मुक्त() को परेशान करने की आवश्यकता नहीं है। @ स्टेव: हटाएं [] एक घृणा है क्योंकि यह अनावश्यक है। यह ऐसा नहीं है, जब आप ऑपरेटर का उपयोग करते हैं और नए नहीं होते हैं [], कि ढेर को जादुई रूप से ब्लॉक के आकार या उसके जैसा कुछ भी स्टोर करने की आवश्यकता नहीं है। – Puppy

6

आप लिखते हैं:

T *p = new T; 

यह एक टी पकड़ करने के लिए पर्याप्त स्मृति आवंटित करता है, तो यह में टी निर्माण करती है। आप लिखते हैं:

T *p = ::operator new(sizeof(T)); 

कि पर्याप्त स्मृति आवंटित करता है एक टी धारण करने के लिए है, लेकिन टी बार आप देख सकते हैं यह है जब लोगों को भी नियुक्ति नए प्रयोग कर रहे हैं में से एक का निर्माण नहीं करता है:

T *p = ::operator new(sizeof(T)); // allocate memory for a T 
new (p) T; // construct a T into the allocated memory 
p->~T(); // destroy the T again 
::operator delete(p); // deallocate the memory 
1

जब आप "कच्चे" मेमोरी के ब्लॉक को आवंटित करना चाहते हैं तो इसका उपयोग करें और उस मेमोरी में कुछ भी नहीं बनाना चाहते हैं।

कच्चे मेमोरी के ब्लॉक को आवंटित करने और वर्णों की एक सरणी "निर्माण" के बीच थोड़ा व्यावहारिक अंतर है लेकिन ऑपरेटर का उपयोग करके स्पष्ट रूप से कोड को पढ़ने वाले किसी भी व्यक्ति को आपके इरादे को स्पष्ट रूप से संकेत मिलता है।

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