/*条款49:了解new-handler的行为*/
#include<iostream>
using namespace std;
//operator new 当无法满足某一内在分配需求时,它会抛出异常,返回NULL指针,某些旧式编译器目前也还那么做,也可以当operator抛出异常之前先调用一个·客户指定错误处理函数(new-handler),但客户必须调用set_new_handler,那是声明于<new>的标准程序库函数
namespace std{
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p)thorw();//当operator new 无法分配足够内在时,set_new_handler则是获得一个new_handler并返回 一个new_handler
}
//这是operator new 无法分配足够内在时set_new_handler,调用的函数
void outOfMem(){
std::cerr<<"Unable to satisfy request for memory\n";
std::abort();
}//主函数进行调用
//一个设计良好的new-handler函数必须做以下事情:
//1 让更多内在可被使用 2 安装另一个new-handler 3 卸除new-handler 也就是让NULL传给set_new_handler 4 抛出bad_alloc(或派生自bad_alloc)的异常 5 不返回 通常是调用abort或exit
class X{
public:
static void outOfMemory();
//..
};
class Y{
public:
static void outOfMemory();
//..
};
// C++ 并不支持class 专属的new-handlers ,w你可以自己实现出这种行为 ,只需令第一个class提供自己的set_new_handler和operator new 即可
template<typename T> // "minxin"风格的基类 用以支持类专属的set_new_handler
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<typename T>
std::new_handler
NewHandlerSupport<T>::set_new_handler(std::new_handler p)throw(){
std::new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
}
template<typename T>
void * NewHandlerSupport<T>::operator new(std::size_t size)throw(std::bad_alloc){
NewHandlerHolder h(std::set_new_handler(currentHandler));
return ::operator new(size);
}
//..
class Widget:public NewHandlerSupport<Widget>{
//....
};//这样就可以为Widget添加set_new_handler ,
class NewHandlerHolder{
public:
explicit NewhandlerHolder(std::new_handler nh):handler(nh){}//取得目前的new-handler
~NewHandlerHolder(){
std::setA_new_handler(handler);
}
private:
std::new_handler handler;// 记录下来
NewHandlerHolder(const NewHandlerHolder&);//阻止copying
NewHandlerHolder&operator=(const NewHandlerHolder&);
}
class Widget{
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;
}
std::new_handler currentHandler = 0;//类外定义,除非它是const型的
std::new_handler set_new_handler(std::new_handler p) throw(){
std::new_handler oldHandler = currentHandler;
currenthandler = p;
return oldhandler;
}
void *Widget::operator new(std::size_t size)throw(std::bad_alloc){
NewHandlerHolder h(std::set_new_handler(currentHandler));//安装widget的new-hanler
return ::operator new(size);//分配内在或抛出异常恢复 glolbe new-handler
}
int main(){
std::set_new_handler(outOfMem);
int *pBigDataArray = new int[100000000L];
X*p1 = new X;//如果分配不成功调用X::outOfMemory
Y*p2 = new Y;
//
void outOfMem(); //函数声明,此函数在widget对象分配失败时被调用
Widget::set_new_handler(outOfMem);//设定outOfMem为Widget的new-handling函数
Widget*pw1 = new widget;//如果内在分配失败,调用 outOfMem;
std::string*ps = new std::string // 如果内在分配失败 调用globe new-handling函数(如果有的话)
Widget::set_new_handler(0);//设定widget专属的new-handling函数为NULL
Widget*pw2 = new Widget;//如果内存分配失败,立刻抛出异常,(class Widget并没有专属的new-handling 函数)
return 0;
}
条款49:了解new-handler的行为
最新推荐文章于 2021-03-20 16:43:26 发布