您的位置:首页 > 其它

异常机制的模拟实现

2013-01-29 12:01 357 查看
在看韩老师的书《老码识途》。其中一章讲异常机制的实现探究。自己上手,先模拟一个。

实现的功能比较简单。

关键函数:

try_()

catch_( hdFunc handle )

finally_( hdFunc handle )

throw_( char *msg )

end_()

ps: typedef void (*hdFunc)( char *msg )

可以看到只能跑出一种错误类型,抛出一个字符串。

catch_()和finally_()必须在紧接在try_()后面调用。

原理就是用栈,每次catch_()和finally_()都会压栈。throw_则出栈,会调用所有的finally,但只会调用离栈顶最进的catch指定的处理函数。

包含 exception.h,stack.h,main.cpp

运行结果是:





下面是代码

stack.h:

[code] #ifndef __STACK_H__


#define __STACK_H__




#pragma once




#define MAXLEVEL 100


#define FLAG_CATCH 1


#define FLAG_FINALLY 2


#define FLAG_ERROR -1


#define EXIT_CODE 1




typedef void (*hdFunc)(char *);




struct s_exception


{


 int flag;


 hdFunc handle;


};




int gStackTop = 0;


s_exception gStack[MAXLEVEL];




s_exception fGetTop()


{


 //do not pop


 s_exception re;


 if( gStackTop <= 0 )


{


 //empty


 re.flag = FLAG_ERROR;


 return re;


}




 re = gStack[ gStackTop - 1 ];


 return re;


}




bool fPush( s_exception v )


{


 if( gStackTop >= MAXLEVEL )


 return false;


 gStack[ gStackTop ] = v;


 ++gStackTop;


 return true;


}




s_exception fPop()


{


 s_exception re;


 if( gStackTop <= 0 )


{


 //empty


 re.flag = FLAG_ERROR;


 return re;


}




 re = gStack[ --gStackTop ];


 return re;


}




#endif

[/code]

exception.h:

[code] #ifndef __EXCEPTION_H__


#define __EXCEPTION_H__




#pragma once




#include "stack.h"


#include <stdlib.h>




int gLvCnt = 0;




void try_()


{


 gLvCnt = 0;


}




void catch_( hdFunc handle )


{


 ++gLvCnt;




 s_exception ex;


 ex.flag = FLAG_CATCH;


 ex.handle = handle;


 fPush( ex );


}




void finally_( hdFunc handle )


{


 ++gLvCnt;




 s_exception ex;


 ex.flag = FLAG_FINALLY;


 ex.handle = handle;


 fPush( ex );


}




void end_()


{


 for( int i = 0;i < gLvCnt;++i )


 fPop();


}




void throw_( char *msg )


{


 //key function. throw exception upward


 while( true )


{


 s_exception ex = fPop();


 if( ex.flag == FLAG_FINALLY )


{


 ex.handle( msg );


}


 else if( ex.flag == FLAG_CATCH )//find it


{


 //终止模型。执行catch以后不恢复


 ex.handle( msg );


 


 while( ex.flag != FLAG_ERROR )


{


 if( ex.flag == FLAG_FINALLY )


 ex.handle( msg );


 ex = fPop();


}




 printf("ready to exit\n");


 system("pause");


 exit(0);//##


}


 else


{


 //error


 exit( EXIT_CODE );


}


}


}




#endif

[/code]

main.h:

[code] #include <stdio.h>


#include <assert.h>


#include "exception.h"




void ca( char *msg )


{


 printf("ca:%s\n",msg);


}




void cb( char *msg )


{


 printf("cb:%s\n",msg);


}




void cc( char *msg )


{


 printf("cc:%s\n",msg);


}




void fa( char *msg )


{


 printf("fa:%s\n",msg);


}




void fb( char *msg )


{


 printf("fb:%s\n",msg);


}




void cfc( char *msg )


{


 printf("cfc:%s\n",msg);


}




void fc( char *msg )


{


 try_();


 catch_( cfc );


 printf("fc:%s\n",msg);


 throw_( "error in fc" );


 end_();


}




void c()


{


 try_();


 finally_(fc);


 throw_( "error in c" );


 end_();


 assert( 0 );//never be to here


}




void b()


{


 try_();


 catch_( cb );


 c();


 end_();


}




void a()


{


 try_();


 catch_( ca );


 finally_( fa );


 b();


 end_();


}




int main()


{


 a();


 return 0;


}

[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: