8、撰写operator new和operator delete时应遵守的公约
1、撰写operator new时应遵守的公约
1.函数行为应该与缺省的operator new保持一致性。即函数应该有正确的返回值:内存不足时调用new_handler,并准备处理内存不足的问题;内存足够时返回一个指针指向他。
2.避免不经意遮掩了正常形式的new。
3.operator new会一再尝试配置内存,每次失败调用错误处理函数。他包含一个无穷循环,且因为他假设错误处理函数包含解决内存不足问题的策略,只有当指向错误处理函数的指针为NULL时,operator new才会抛出exception;只有成功配置内存时,operator new会传回一个指针。
4.即使需求为0bytes,operator new也应该传回一个合法指针。
void * operator new(size_t size)
{
if (size == 0) {
size = 1;
}
while (true) {
...//配置内存,配置成功传回一个指针
//配置不成功时,找出错误处理函数
new_handler globalHandler = set_new_handler(0);
set_new_handler(globalHandler);
if (globalHandler) (*globalHandler) ();
else throw std::bad_alloc();
}
}
5.class专属的operator new可被子类继承,故应考虑父类的operator new被用来配置子类对象的情况。当要配置的内存与父类占用内存不一致时,交给::operator new处理。
6.实现class专属的operator new[]时,其唯一做的就是配置未处理的内存,因为并不知道是父类还是子类对象,不知道所占用的内存大小、对象数量,所以不对这块内存做任何处理,仅仅是配置一块内存。
class Base {
public:
static void * operator new (size_t size);
...
};
void * Base::operator new (size_t size)
{
if (size != sizeof(Base)
return ::operator new(size);
...
}
2、撰写operator delete时应遵守的公约
1.保证,删除一个NULL指针是安全的。
void operator delete (void *rawMemory)
{
if (rawMemory == 0) return;
...
}
2.class专属的operator delete时,与operator new对应,亦可被子类继承。故当要配置的内存与父类占用内存不一致时,交给::operator delete处理。
class Base {
public:
static void * operator new (size_t size);
static void operator delete (void *rawMemory, size_t size);
};
void Base::operator delete (void *rawMemory, size_t size)
{
if (rawMemory == 0) return;
if (size != sizeof(Base)) {
::operator delete(rawMemory);
return;
}
...
}