/*條款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的行爲
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.