[原创文章欢迎转载,但请保留作者信息]
Justin 于 2010-05-25
到了七七四九章,大师已经带领我们走进了全书的第八部分:定制new和delete。往往只有掌握了程序背后的内存管理机制,才能真正做到对程序的控制。上课上到这里,恭喜你慢慢在进步了。
Item49要讲的是当new失败时,负责异常处理的new handler程序。大师说一个合格的new handler应该具备下面的特征:
- 可以“挤”出更多的可用内存。本来喊你来就是因为没有内存可以用,这个算是个最基本的要求了。
- 当无法安排出更多可用内存时,要有下一步的解决方案。比如说找另外一个人来帮忙(通过set_new_handler来设置调用另一个new handler),或是变身为超人(通过改变函数自身的行为来进一步分配可用内存,说穿了就是类似下面的处理过程,当然实际并没有那么简单)
if (! failed)
{
//do the normal new exception handling
if ( cannot_make_more_memory_available )
failed = 1;
} else {
//do another way around to get more memory
}
- 应该可以“卸载”new handler。也就是说可以禁止对new失败时进行任何处理,或者说是关掉new handler,此时new的失败会直接抛出异常。
- 应该在无法安排更多可用内存时抛出bad_alloc或类似的异常,以让申请内存的家伙知道这次没有面包吃了。
- 不会返回,一般而言,意味着该函数应该以abort或是exit自我了断。
在C++中可以专门为某个类实现其专属的new handler,只要正确利用set_new_handler()就可以了。
接下来大师写了一个通用的模板类,帮助另外一个类实现安装/卸载特定的new handler。它的设计很简单,在调用new之前安装指定的new handler,调用结束后卸载并恢复原先的全局handler。安装new handler的函数、重载的new函数以及用于暂时保存new handler的函数指针都是静态的(static),这样做的目的是可以基于模板类的每个模板参数生成一套专属的实例。例子在书上,就不画蛇添足了。