- operator new在内存不足时会调用new-handling函数。operator new如果有返回值就返指针指向的内存,否则抛出bad_alloc异常,即当new-handling函数的指针是null时,operator new才会抛出异常。
template<typename T>
class NewHandlerSupport {
public:
static std::new_handler set_new_handler(std::new_hadler p) throw();
static void* operator new(std::size_t size) throw(std::bad_alloc);
...
private:
static std::new_hadler currentHandler;
};
template<typename T>
std::new_handler NewHandlerSupport<T>::set_new_handler(std::new_handler p) throw(){
std::new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
}
template<typename T>
void* NewHandlerSupport<T>::operator new(std::size_t size) throw(std::bad_alloc){
NewHandlerHolder h(std::set_new_handler(currentHandler));
return ::operator new(size);
}
template<typename T>
std::new_handler NewHandlerSupport<T>::currentHandler = 0;
c++规定中,即使客户申请0bytes,operator new也返回一个合法的指针,视为1byte。
- operator new内含一个无穷循环,并尝试分配内存,如果无法满足内存需求,就调用new-handler,同时也需要有能力处理0bytes。
// 非成员函数
void operator delete(void* rawMemory) throw(){
if(rawMemory == 0) return; // 如果被删除的是null指针,就直接返回,不做任何操作
}
// 成员函数
class Base{
public:
static void* operator new(std::size_t size) throw(std::bad_alloc);
static void operator delete(void* rawMemory, std::size_t size) throw();
...
};
void Base::operator delete(void* rawMenory, std::size_t size) throw(){
if(rawMemory == 0) return;
if(size != sizeof(Base)){
::operator delete(rawMemory); // 如果大小不一致,使用标准版本
return;
}
return;
}
- 当使用placement operator new时,也要同时对应placement operator delete,同时不要无意识地掩盖它们的正确版本。
class Standard New Delete Forms{
public:
// normal new/delete
static void* operator new(std::size_t size) throw(std::bad_alloc){
return ::operator new(size);
}
static void operator delete(void* pMemory) throw(){
::operator delete(pMemory);
}
//placement new/delete
static void* operator new(std::size_t size, void* ptr) throw(){
return ::operator new(size, ptr);
}
static void operator delete(void* pMemory, void* ptr) throw(){
::operator delete(pMemory, ptr);
}
//nothrow new/delete
static void* operator new(std::size_t size, const std::nothrow_t& nt) throw(){
return ::operator new(size, nt);
}
static void operator delete(void* pMemory, const std::nothrow_t& nt) throw(){
::operator delete(pMemory, nt);
}
}
class Widget : public StandardNewDeleteForms{
public:
using StandardNewDeleteForms::operator new;
using StandardNewDeleteForms::operator delete;
static void* operator new(std::size_t size, std::ostream& logStream) throw(std::bad_alloc);
static void operator delete(void* pMemory, std::ostream& logStream) throw();
};