लघु जवाब:
इस प्रयोग के लिए कोई सीधा समर्थन नहीं है। यदि आप एक अलग हस्ताक्षर के साथ नया अधिभारित करते हैं, तो संकलक इसे नए अधिभार (नए प्लेसमेंट नहीं) मानता है और अपना स्वयं का बुक-रखरखाव कोड जोड़ता है। कंपाइलर को कहने के लिए कोई रास्ता नहीं है (मुझे मिल सकता है) "अपनी पुस्तक-रखरखाव को खोलें, और इस हस्ताक्षर से मेल खाने वाले मेरे डिलीट ओवरलोड को कॉल करें" - यह केवल void operator delete(void* p)
या void operator delete[](void* p)
पर कॉल करते समय पुस्तक-पालन को अनदेखा करने के लिए कोड डालेगा।
यदि आप नए हस्ताक्षर के साथ नए ओवरराइड करते हैं, तो संकलक आपको नए के दौरान अपवादों के मामले में मिलान करने वाले हस्ताक्षर के साथ एक डिलीट को परिभाषित करना पसंद करता है - यह एकमात्र समय होता है।
इस बात में कोई प्लेसमेंट हटा नहीं है कि यह कॉल करने योग्य नहीं है, लेकिन अपवादों (कुछ भी करने के लिए) में यह परिभाषित नहीं किया गया है।
लांग जवाब:
इस विषय में कुछ रोचक अंक को जन्म देती है:
- क्या, वास्तव में,
void* operator new[](size_t sz, Allocator* a)
अधिभार करता है?
- क्या वहां है, या "प्लेसमेंट डिलीट" नहीं है।
- कोई व्यक्ति
void operator delete[](void* p, Allocator* a)
कैसे आमंत्रित करता है, इस तरह से संकलक अपनी पुस्तक-रखरखाव अंतिम रूप देता है?
प्वाइंट 1: नियुक्ति को ओवरलोड करने के बारे में बहुत कुछ बात। यह देखते हुए कि संकलक पुस्तक रखने के कोड को सम्मिलित कर रहा है, यह राय होना चाहिए कि void* operator new[](size_t sz, Allocator* a)
एक ओवरलोड (गैर-प्लेसमेंट) नया घोषित करता है। यह नियुक्ति के लिए पुस्तक-पालन कोड कभी भी नहीं डालेगा, क्योंकि प्लेसमेंट का बिंदु नया है कि आप इसे स्वयं संभालने वाले हैं।
प्वाइंट 2: आरई। "प्लेसमेंट डिलीट जैसी कोई चीज़ नहीं है", आपको ऐसा कुछ मिल जाएगा जो इस तरह से दिखता है (और इस तरह टिप्पणी करता है) उदा। वीएस 2 के 8 नया हेडर। यह केवल उन मामलों में उपयोग किया जाता है जहां नियुक्ति के दौरान अपवाद होता है। हालांकि यह सच साबित होता है कि आप सार्थक तरीके से नियुक्ति हटा नहीं सकते हैं।
प्वाइंट 3: यदि कोई रास्ता है, तो मुझे यह नहीं मिल रहा है। यह समस्या का दिल है।
समस्या के व्यावहारिक समाधान के संदर्भ में, यह एक बस्ट प्रतीत होता है।
उदाहरण के लिए
:
//intention: user provides memory pool, compiler works out how many bytes required
//and does its own book-keeping, as it would for a void* operator new[](size_t sz) overload
//calling syntax: CObj* pMyArr = new(pMyMemPool) CObj[20];
void* operator new[](size_t sz, IAlloc* pMemPool)
{ return pMemPool->alloc(sz); }
//problem: don't know the syntax to call this!
//e.g. delete[](pMyMemPool) pMyArr is syntax error
void* operator delete[](void* p, IAlloc* pMemPool)
{ return pMemPool->free(p); }
//nb: can be called as operator delete(pMyArr, pMyMemPool);
//but compiler does not finish its book-keeping or call dtors for you in that case.
ध्यान दें कि यह विषमता नया गैर सरणी के लिए मौजूद है & भी हटा सकते हैं। हालांकि, क्योंकि (अनुभवजन्य) प्रश्न में संकलक कोई अतिरिक्त पुस्तक-पालन नहीं करता है, इसे सभी को काम करने के लिए बनाया जा सकता है। दोबारा, अगर यह मानक में निहित है तो मुझे नहीं पता।
void* operator new(size_t sz, IAlloc* pMemPool)
{ return pMemPool->alloc(sz); }
//don't know syntax to get this called by compiler!
void operator delete(void* p, IAlloc* pMemPool)
{ pMemPool->free(p); }
//is ok though, can work around
template<class T> void tdelete(void* p, IAlloc* pMemPool)
{
//no problems, p points straight at object
p->~T();
operator delete(p, pMemPool);
//OR just
pMemPool->free(p);
}
void* operator new[](size_t sz, IAlloc* pMemPool)
{ return pMemPool->alloc(sz); }
//again, don't know syntax to end up here.
void operator delete[](void* p, IAlloc* pMemPool)
{ pMemPool->free(p); }
//can't work around this time!
template<class T> void tarrdelete(void* p, IAlloc* pMemPool)
{
//problem 1: how many to dtor?
for(int i=0; i<???; ++i)
{ reinterpret_cast<T*>(p+i)->~T(); }
//problem 2: p points at first element in array. this is not always the address
//that was allocated originally.
pMemPool->free(?);
//as already explained by OP, no way to tell if p is address allocated or
//address allocated+4 bytes, or something else altogether. this means no way to know what address to un-alloc or how many dtors to call.
}
अंत में, मैं obvs राज्य होगा।
//sz may include extra for book-keeping
void* operator new[](size_t sz)
{ return GAlloc->alloc(sz); }
//works fine, compiler handled book-keeping and p is the pointer you allocated
void operator delete[](void* p)
{ return GAlloc->free(p); }
सारांश: वहाँ वाक्य रचना कि संकलक "जादू" सक्षम के साथ, एक विस्तारित पैरामीटर सूची के साथ हटाना की एक अधिभार के लिए कॉल की अनुमति देगा है - विस्तारित पैरामीटर सूची के बिना भार के काम करते हैं। या, ओवरराइड द्वारा प्लेसमेंट नए में पैरामीटर जोड़ने का कोई तरीका है?
संदिग्ध जवाब: नहीं
उपप्रमेय: आप 6 में निर्मित पूरी स्वतंत्रता के साथ नए हस्ताक्षर से दूर नहीं कर सकते। ऐसा करने के परिणामस्वरूप संकलक उत्पन्न पुस्तक-रखरखाव के साथ नए ओवरलोड में परिणाम मिलता है, लेकिन बुक-रख-रखाव से बाहर निकलने के लिए संबंधित डिलीट तक पहुंच नहीं होती है।
कैविट: आप अंतर्निहित हस्ताक्षर से भटक सकते हैं, लेकिन केवल कोड इंजेक्ट करने के लिए आपको हटाने (उदा। उपकरण) पर फिर से संभालने की आवश्यकता नहीं है। यदि आप आवंटन के लिए void* operator new(size_t s)
संस्करण तक पहुंचते हैं, तो हटाएं अभी भी सामान्य के रूप में काम करेंगे।
(वास्तव में से कुछ बयान डीबगर में प्रयोगों से तैयार कर रहे हैं और केवल MSVC8 (Cl9) के लिए आवेदन कर सकते हैं। ओपी मेरे बगल में डेस्क पर बैठता है।)
आप "प्लेसमेंट को हटा" ओवरराइड नहीं करें यहाँ। –
अगर alignof (MyClass) == 8, मैं शर्त लगाता हूं कि pa _not_ buf + 4. – Bahbar
सत्य है, लेकिन मुझे लगता है कि मैं आकार प्राप्त कर सकता हूं, मुझे अभी भी पता नहीं है कि कंपाइलर ने इसे रखा है या नहीं। यदि MyClass में कोई dtor pA == buf नहीं है। – Gwaredd