在看韩老师的书《老码识途》。其中一章讲异常机制的实现探究。自己上手,先模拟一个。
实现的功能比较简单。
关键函数:
- 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:
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: }