• 异常机制的模拟实现


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

    实现的功能比较简单。

    关键函数:

    • 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: }
  • 相关阅读:
    docker进入容器命令
    docker复制文件到容器内以及从容器内复制文件到宿主机
    在idea中创建maven父子工程,子工程无法导入父工程依赖的问题
    maven merge 其他分支比如master的方法
    Maven 右边的maven 项目为空 pom文件
    Spark Streaming集成Kafka调优
    spark sql/hive小文件问题
    CompletableFuture详解
    样式绑定styleBinding
    jsonArray图片数组实例
  • 原文地址:https://www.cnblogs.com/nanshu/p/2881198.html
Copyright © 2020-2023  润新知