条款49:了解new-handler的行为

/*条款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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值