簡短的回答:
有這個用法沒有直接的支持。如果您使用不同的簽名重新載入新內容,編譯器認爲它是新的重載(而不是新的位置),並添加了自己的簿記代碼。沒有辦法(我可以找到)對編譯器說「放鬆你的記錄,並打電話給我的刪除過載符合這個簽名」 - 當調用void operator delete(void* p)
或void operator delete[](void* p)
時,它只會插入代碼以展開記錄。
如果您使用新簽名重寫new,編譯器會讓您在新建期間出現異常時定義具有匹配簽名的刪除 - 這是它唯一使用的時間。
沒有放置刪除的意思,它不可調用,但它是在例外(什麼都不做)的情況下定義的。
龍答:
本主題提出了一些有趣的觀點:
- 究竟什麼呢
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點:R.E. 「不存在刪除位置信息」這樣的事情,你會發現一些看起來非常喜歡(並且如此評論)的東西。 VS2k8新的標題。它只是一個存根,用於在新放置期間發生異常的情況。不過,您確實無法以有意義的方式調用展示位置刪除。
第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(C 1-9)。OP坐在桌子旁邊給我。)
你不越權「位置刪除」在這裏。 – 2009-11-27 16:50:26
如果alignof(MyClass)== 8,我會打賭pa是_not_ buf + 4. – Bahbar 2009-11-27 16:57:37
是真的,但假設我可以獲得大小,我仍然不知道編譯器是否已將它放入。如果MyClass沒有dtor pA == buf。 – Gwaredd 2009-11-27 17:40:27