后看看x的operator new所做的:

  1、调用标准set_new_handler函数,输入参数为x的出错处理函数。这使得x的new-handler函数成为全局new-handler函数。注意下面的代码中,用了"::"符号显式地引用std空间(标准set_new_handler函数存在于std空间)。

  2、调用全局operator new分配内存。如果第一次分配失败,全局operator new会调用x的new-handler,因为它刚刚(见1.)被安装成为全局new-handler。如果全局operator new终未能分配到内存,它抛出std::bad_alloc异常,x的operator new会捕捉到它。x的operator new然后恢复初被取代的全局new-handler函数,后以抛出异常返回。

  3、假设全局operator new为类型x的对象分配内存成功,, x的operator new会再次调用标准set_new_handler来恢复初的全局出错处理函数。后返回分配成功的内存的指针。

  c++是这么做的:


void * x::operator new(size_t size)
{
 new_handler globalhandler =  // 安装x的new_handler
   
  std::set_new_handler(currenthandler);
 
void *memory;

try {  // 尝试分配内存
 memory = ::operator new(size);
}


catch (std::bad_alloc&) {  // 恢复旧的new_handler
 std::set_new_handler(globalhandler);     
 throw; // 抛出异常
}
 std::set_new_handler(globalhandler); // 恢复旧的new_handler
 return memory;
}

  如果你对上面重复调用std::set_new_handler看不顺眼,可以参见条款m9来除去它们。

  使用类x的内存分配处理功能时大致如下:


void nomorememory();// x的对象分配内存失败时调用的new_handler函数的声明

x::set_new_handler(nomorememory);
  // 把nomorememory设置为x的
  // new-handling函数

x *px1 = new x;
  // 如内存分配失败,
  // 调用nomorememory
string *ps = new string;
  // 如内存分配失败,调用全局new-handling函数
 
x::set_new_handler(0);
  // 设x的new-handling函数为空
 
x *px2 = new x;
  // 如内存分配失败,立即抛出异常
  // (类x没有new-handling函数)


  你会注意到,处理以上类似情况,如果不考虑类的话,实现代码是一样的,这很自然地想到在别的地方也能重用它们。正如条款41所说明的,继承和模板可以用来设计可重用代码。在这里,我们把两种方法结合起来使用,从而满足了你的要求。