(六)
可以将上述方法抽象,建立mixin风格的基类,它允许派生类继承单一特定能力(这里是“设定该类专属的new-handler“),并把该基类抽象为模板类以提高复用性。
代码如下:
template因为对于class里面的static成员变量的初始化必须要在class的外面定义。class NewHandlerSupport { public: static std::new_handler set_new_handler(std::new_handler p) throw(); static void* operator new(std::size_t size) throw(std::bad_alloc); private: static std::new_handler currentHandler; }; template std::new_handler NewHandlerHolder ::set_new_handler(std::new_handler p) throw() { std::new_handler oldHandler = currentHandler; currentHandler = p; return oldHandler; } template void* NewHandlerSupport ::operator new(std::size_t size) throw(std::bad_alloc){ NewHandlerHolder h(std::set_new_handler(currentHandler)); return ::operator new(size); }
所以以下是将每一个currentHandler初始化为null
templatestd::new_handler NewHandlerSupport ::currentHandler = 0;
(七)
对于一个具体的类,添加专属的set_new_handler就很容易了:继承。
class Widget : public NewHandlerSupport{ ... //和先前一样,但不必声明set_new_handler或operator new };
(八)
6.旧式的operator new在内存分配失败后返回null,为了兼容旧代码,C++提供了另
一形式的operator new,称为nothrow形式,在new使用的场合使用了nothrow对象(定义于头文件中)。建议不要使用。因为如果构造函数也抛出异常的话,那样的话会产生递归发生异常。
请记住:
(1)set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用。
(2)Nothrow new是一个颇为局限的工具,因为它只适用于内存分配;后继的构造函数调用还是有可能抛出异常的。