异常机制的模拟实现

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

实现的功能比较简单。

关键函数:

  • 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  

运行结果是:

1

下面是代码

stack.h:

   1: #ifndef __STACK_H__
   2: #define __STACK_H__
   3:  
   4: #pragma once
   5:  
   6: #define MAXLEVEL 100
   7: #define FLAG_CATCH 1
   8: #define FLAG_FINALLY 2
   9: #define FLAG_ERROR -1
  10: #define EXIT_CODE 1
  11:  
  12: typedef void (*hdFunc)(char *);
  13:  
  14: struct s_exception
  15: {
  16:     int flag;
  17:     hdFunc handle;
  18: };
  19:  
  20: int gStackTop = 0;
  21: s_exception gStack[MAXLEVEL];
  22:  
  23: s_exception fGetTop()
  24: {
  25:     //do not pop
  26:     s_exception re;
  27:     if( gStackTop <= 0 )
  28:     {
  29:         //empty
  30:         re.flag = FLAG_ERROR;
  31:         return re;
  32:     }
  33:  
  34:     re = gStack[ gStackTop - 1 ];
  35:     return re;
  36: }
  37:  
  38: bool fPush( s_exception v )
  39: {
  40:     if( gStackTop >= MAXLEVEL )
  41:         return false;
  42:     gStack[ gStackTop ] = v;
  43:     ++gStackTop;
  44:     return true;
  45: }
  46:  
  47: s_exception fPop()
  48: {
  49:     s_exception re;
  50:     if( gStackTop <= 0 )
  51:     {
  52:         //empty
  53:         re.flag = FLAG_ERROR;
  54:         return re;
  55:     }
  56:  
  57:     re = gStack[ --gStackTop ];
  58:     return re;
  59: }
  60:  
  61: #endif

exception.h:

   1: #ifndef __EXCEPTION_H__
   2: #define __EXCEPTION_H__
   3:  
   4: #pragma once
   5:  
   6: #include "stack.h"
   7: #include <stdlib.h>
   8:  
   9: int gLvCnt = 0;
  10:  
  11: void try_()
  12: {
  13:     gLvCnt = 0;
  14: }
  15:  
  16: void catch_( hdFunc handle )
  17: {
  18:     ++gLvCnt;
  19:  
  20:     s_exception ex;
  21:     ex.flag = FLAG_CATCH;
  22:     ex.handle = handle;
  23:     fPush( ex );
  24: }
  25:  
  26: void finally_( hdFunc handle )
  27: {
  28:     ++gLvCnt;
  29:  
  30:     s_exception ex;
  31:     ex.flag = FLAG_FINALLY;
  32:     ex.handle = handle;
  33:     fPush( ex );
  34: }
  35:  
  36: void end_()
  37: {
  38:     for( int i = 0;i < gLvCnt;++i )
  39:         fPop();
  40: }
  41:  
  42: void throw_( char *msg )
  43: {
  44:     //key function.   throw exception upward
  45:     while( true )
  46:     {
  47:         s_exception ex = fPop();
  48:         if( ex.flag == FLAG_FINALLY )
  49:         {
  50:             ex.handle( msg );
  51:         }
  52:         else if( ex.flag == FLAG_CATCH )    //find it
  53:         {
  54:             //终止模型。执行catch以后不恢复
  55:             ex.handle( msg );
  56:             
  57:             while( ex.flag != FLAG_ERROR )
  58:             {
  59:                 if( ex.flag == FLAG_FINALLY )
  60:                     ex.handle( msg );
  61:                 ex = fPop();
  62:             }
  63:  
  64:             printf("ready to exit\n");
  65:             system("pause");
  66:             exit(0);    //##
  67:         }
  68:         else
  69:         {
  70:             //error
  71:             exit( EXIT_CODE );
  72:         }
  73:     }
  74: }
  75:  
  76: #endif

main.h:

   1: #include <stdio.h>
   2: #include <assert.h>
   3: #include "exception.h"
   4:  
   5: void ca( char *msg )
   6: {
   7:     printf("ca:%s\n",msg);
   8: }
   9:  
  10: void cb( char *msg )
  11: {
  12:     printf("cb:%s\n",msg);
  13: }
  14:  
  15: void cc( char *msg )
  16: {
  17:     printf("cc:%s\n",msg);
  18: }
  19:  
  20: void fa( char *msg )
  21: {
  22:     printf("fa:%s\n",msg);
  23: }
  24:  
  25: void fb( char *msg )
  26: {
  27:     printf("fb:%s\n",msg);
  28: }
  29:  
  30: void cfc( char *msg )
  31: {
  32:     printf("cfc:%s\n",msg);
  33: }
  34:  
  35: void fc( char *msg )
  36: {
  37:     try_();
  38:     catch_( cfc );
  39:     printf("fc:%s\n",msg);
  40:     throw_( "error in fc" );
  41:     end_();
  42: }
  43:  
  44: void c()
  45: {
  46:     try_();
  47:     finally_(fc);
  48:     throw_( "error in c" );
  49:     end_();
  50:     assert( 0 );    //never be to here
  51: }
  52:  
  53: void b()
  54: {
  55:     try_();
  56:     catch_( cb );
  57:     c();
  58:     end_();
  59: }
  60:  
  61: void a()
  62: {
  63:     try_();
  64:     catch_( ca );
  65:     finally_( fa );
  66:     b();
  67:     end_();
  68: }
  69:  
  70: int main()
  71: {
  72:     a();
  73:     return 0;
  74: }
posted @ 2013-01-29 12:01  南树  阅读(523)  评论(0编辑  收藏  举报