author:
- luixiao1223
title: 编写new和delete时需固守常规
new
- 如果顺利返回指针
- 如果不顺利, 调用new handler(希望它可以做些什么).
- 如果没有new handler则返回
=bad_alloc=
void* operator new(std::size_t size) throw(std::bad_alloc)
{
using namespace std;
if (size == 0) {
size = 1;
}
while (true) {
if ( the allocation was successful)
return (a pointer to the memory);
new_handler globalHandler = set_new_handler(0);// 你没有其它办法拿到new_handler,只能这样拿,如果是多线程,你需要注意在这里加锁.
set_new_handler(globalHandler);
if (globalHandler) (*globalHandler)();
else throw std::bad_alloc();
}
}
注意
如果new operator定义在class.而class被继承了.就不会对劲了.
class Base {
public:
static void* operator new(std::size_t size) throw(std::bad_alloc);
...
};
class Derived: public Base
{ ... };
Derived *p = new Derived;
void* Base::operator new(std::size_t size) throw(std::bad_alloc)
{
if (size != sizeof(Base)) // 如果是derived class来调用new
return ::operator new(size);
}
array new
=operator new[]=
对于这个内存分配,也应该注意,你不应该假设要分配的内存为sizeof(base)*count.因为,继承的class可能也会调用这个operator.所以你只能按照传递进来的数据大小进行分配内存.
delete
对于delete需要注意一点就是,删除null指针永远安全.
void operator delete(void *rawMemory) throw()
{
if (rawMemory == 0) return;
// 归还内存
}
class内的operator
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 *rawMemory, std::size_t size) throw()
{
if (rawMemory == 0) return;
if (size != sizeof(Base)) { // 如果是derived class调用释放操作,则交给常规的释放操作符
::operator delete(rawMemory);
return;
}
return;
}
注意:
别忘记了virtual函数的重要性.如果你忘记设置virtual属性.那么不能保证delete的正确性.