exception 的實現

據我所知有2種方法,動態和靜態
動態是編譯器幫你插入一堆代碼(關鍵性的代碼就是setjmp和
longjmp),在你每個throw catch的地方都插入這些代碼,會
影響整體性能(這個不需要什麼系統相關的東西就能實現)

靜態的就是生成一個expection handler的查找表,然後每次
拋出的時候就去查那麼一查,如果沒有異常情況的話,這個方式
開銷低,但是這個就要和操作系統相關了,如果虛擬機就
。。。嘿嘿。


然後,簡單的說一下動態方法,我具體代碼懶的寫(其實怕寫不出)
給一點僞代碼:

struct Exception{
char* name;
int typecode;
//...others
};

int HashFun(char*)//這個函數把字符串搞成int,是唯一對應的
{...}

Exception* CreateException(char* name)//新建一個exception
{..}

void FreeException(Exception*)//銷燬它!
{..}

//--------------------------------------------------------
struct ExceptionHandler
{
int typecode;
jmp_buf location; //這裏是比較重要的。。。
};
struct ExceptionHandlerStack
{ int size;//現在list的大小
  ExceptionHandler list[MAX]; //一個Handler的鏈
  ExceptionHandlerStack(); //初始化工作
~ExceptionHanclerStack();//銷燬工作。。。
  static ExceptionHandler* Push(char*name)  //根據name,用hash函數生成typecod
e,然後填入  鏈最後一個Handler裏面,然後返回它
  static Pop();//嗯。。。很明顯
  static void throwException(Exception *ex)//拋出異常
  {
     在鏈裏面找啊找,找到了typecode相同的Handler就
     longjmp(list[size].location,(int)ex); //關鍵函數。。。
  }
};

好基本實現差不多了,然後講編譯器插入的代碼
本來是:
void Fun()
{
try{
    Excetpion *ex;
    ex = CreateException("name");
     throwException(ex);
}catch(Exception *ex)
{
   dosomething(ex);
}
好了,編譯器改成。。。
void Fun()
{
ExceptionHandler* hd;
int ret;
hd = ExceptionhandlerList::push("name");
ret = setjmp(hd->location);
if(ret ==0)
{ Excetpion* ex;
  ex = CreateException("name);
  ExcetpionhandlerList::throwException(ex);
}else
{  Exception* ex;
   ex = (exception*)ret;
   dosomething(ex);
  FreeException(ex);
  }
ExceptionHanclerList::pop(hd);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章