C++ new、delete(new[]、delete[])操作符重载需要注意的问题(2)
这一些方面是我们需要注意的:operator new 可以接受 size 为 0 的内存分配且返回一个有效的指针;如果存在 new-handling function 那么在内存分配失败时会调用它并且再次尝试内存分配;如果不存在 new-handling function 失败时抛出 bad_alloc 异常。
要注意的是,一旦设置了 new-handling function 内存分配就会无限循环进行下去,为了避免无限循环的发生,new-handling function 必须做以下几件事中的一件(详细参考《Effective C++ Third Edition》 Item 49):让有更多内存可用、设置另一个能发挥作用的 new-handler、删除当前的 new handler、抛出一个异常(bad_alloc 或者继承于 bad_alloc)、直接调用 abort() 或者 exit() 等函数。
对于 operator delete 的异常处理就简单一些,只需要保证能够安全的 delete 空指针即可:
void operator delete(void *rawMemory) throw()
{
// 操作符可以接受空指针
if (rawMemory == 0) return;
释放内存
}
多态的问题(详细参考《ISO/IEC 14882》)
前面谈到了 new、delete(new[]、delete[])操作符的继承,这里额外讨论一下多态的问题,显然我们只需要讨论 delete、delete[] 操作符:
struct B {
virtual ~B();
void operator delete(void*, size_t);
};
struct D : B {
void operator delete(void*);
};
void f()
{
B* bp = new D;
delete bp; //1: uses D::operator delete(void*)
}
通过上面的例子,我们可以看到,delete 时正确的调用了 D 的 operator delete 操作符。但是同样的,对于 delete[] 操作符工作就不正常了(因为对于 delete[] 操作符的检查是静态的):
struct B {
virtual ~B();
void operator delete[](void*, size_t);
};
struct D : B {
void operator delete[](void*, size_t);
};
void f(int i)
{
D* dp = new D[i];
delete [] dp; //uses D::operator delete[](void*, size_t)
B* bp = new D[i];
delete[] bp; //undefined behavior
}
- 上一篇:VC实现的病毒专杀工具完整实例
- 下一篇:VC多线程编程详解