c/c++的异常统一处理

来源:互联网 发布:有点儿意思 软件下载 编辑:程序博客网 时间:2024/04/30 21:22

今天看HTK代码,发现里面的错误处理机制很好,所以自己在这里总结一下。如何将某些类型的错误集中起来统一处理,使得程序易于维护和具有更好的可读性。

这里假设有这样一个故事,有个美女征婚,理想中的男人如果要表白成功,需要具备6个条件:玫瑰(Rose),戒指(Ring),宝马(BWM),高(Tall),富(Rich),帅(Handsome)。(好吧,我承认这个故事很低俗,但是实在想不出其它例子来比喻了,将就着看吧,-_-)。如果少了一个条件,sorry,美女要抛出异常了。但是现在求婚的人太多,美女无暇顾及,所以决定先请人把关,再根据把关人反馈的结果统一处理。好了,先看C语言如何处理:

C语言错误统一处理

 1 #include <stdio.h> 2 #include <memory.h> 3 #include <stdarg.h> 4 #define COUNT 6 5 static char *pall[]={"Ring", "Rose", "BMW", "Tall", "Rich", "Handsome"}; 6   7  8 typedef struct _Condition { 9          char *pgift[COUNT];10          int ngift;11 }Condition;//存储个人条件的结构体12 static void Select(const Condition *con);13 static void Herror(int ntype, char *str, ...);14 int main(int argc, char **argv)15 {16          Condition A,B,C;17          memset(A.pgift, 0, COUNT);18          memset(B.pgift, 0, COUNT);19          memset(C.pgift, 0, COUNT);20          A.pgift[1]=pall[1]; A.ngift=1;//A->Rose21          B.pgift[0]=pall[0]; B.pgift[5]=pall[5]; B.ngift=2;//B->Ring,Handsome22          C.pgift[1]=pall[1]; C.pgift[2]=pall[2]; C.pgift[4]=pall[4]; C.ngift=3;//C->Rose,BMW,Rich23          24          Select(&A);25          Select(&B);26          Select(&C);27          return 0;28 }29 /*****************************************30 *根据条件考虑每个人,并调用错误统一处理函数31 ******************************************/32 static void Select(const Condition *con)33 {34          if(con==NULL)35                    return;36          switch(con->ngift)37          {38                    case 0:39                             break;40                    case 1:41                             Herror(1, "fail:only have %s", con->pgift[1]);42                             break;43                    case 2:44                             Herror(2, "fail:only have %s,%s", con->pgift[0], con->pgift[5]);45                             break;46                    case 3:47                             Herror(3, "fail:only have %s,%s,%s", con->pgift[1], con->pgift[2], con->pgift[4]);48                             break;49                    default:50                             break;51          }52 }53 /********************************************54 * 统一处理55 * *****************************************/56 static void Herror(int ntype, char *str, ...)57 {58          va_list parg;59          FILE *f = stdout;60          va_start(parg, str);//获取指向可变参数的第一个参数的指针61          printf("\n---------Result--------\n");62          if(ntype < 3)63                    printf("pass over:");64          else if(ntype < 5)65                    printf("just so so:");66          else67                    printf("wait and see:");68          vfprintf(f, str, parg);//输出结果69          printf("\n----------over---------\n");70          va_end(parg);//关闭指针71          fflush(f);   72 }

结构体中的ngift表示男人征婚准备的礼物数量。32行的select函数所做的工作就是把关,考擦每个男人的条件,对于不符合美女要求的,统一把把关结果反馈给Herror函数,这里Herror做的事情就是美女根据反馈结果下结论:ngift<3的直接pass掉(这美女有点物质,哈哈),介于3与5之间的她觉得一般般,只有大于5时,她决定再看看。这就完成了错误的处理过程。

值得说一下的是,Herror的最后参数是一个可变形参,所以具有更大的灵活性,便于程序的扩展。其中可变形参的获取用到了va_start和va_end宏,这个宏在标准库<stdarg.h>中定义。详细的使用说明可以去网上搜一下。

 

C++的统一异常处理

 C++提供了异常处理的一个类:exception。为了解决我们自己碰到的异常,只需要继承这个类,并重载或自定义一些错误处理函数即可实现。同样是上面的列子,我们改动一下:

  1 #include <iostream>  2 #include <cstdlib>  3 using namespace std;  4 #define COUNT 6  5 static char *pall[]={"Ring", "Rose", "BMW", "Tall", "Rich", "Handsome"};  6   7 typedef struct _Condition {  8     char *pgift[COUNT];  9     int ngift; 10 }Condition; 11  12 class MyException:public exception 13 { 14 public: 15     MyException():m_ntype(-1),m_str(NULL) {} 16     MyException(int n, char *p):m_ntype(n),m_str(p) {} 17     char* Deal() const throw(); 18     ~MyException() 19     { 20         if(m_str) 21         { 22             delete m_str; 23             m_str = NULL; 24         } 25     } 26 private: 27     int m_ntype; 28     char *m_str; 29 }; 30 static void Select(const Condition *con); 31  32 int main(int argc, char **argv) 33 { 34     Condition A,B,C; 35     Condition *pcon[3]; 36     memset(A.pgift, 0, COUNT); 37     memset(B.pgift, 0, COUNT); 38     memset(C.pgift, 0, COUNT); 39     A.pgift[1]=pall[1]; A.ngift=1;//A->Rose 40     B.pgift[0]=pall[0]; B.pgift[5]=pall[5]; B.ngift=2;//B->Ring,Handsome 41     C.pgift[1]=pall[1]; C.pgift[2]=pall[2]; C.pgift[4]=pall[4]; C.ngift=3;//C->Rose,BMW,Rich 42     pcon[0] = &A; pcon[1] = &B; pcon[2] = &C; 43  44     for (int i=0; i<3; i++) 45     { 46         try 47         { 48             Select(pcon[i]); 49         } 50         catch (MyException &e) 51         { 52             char *ptemp; 53             ptemp = e.Deal(); 54             if (ptemp!=NULL) 55             { 56                 printf("\n---------Result--------\n"); 57                 cout<<ptemp<<endl; 58                 printf("\n----------over---------\n"); 59                 delete ptemp; 60             }     61         } 62     } 63     return 0; 64 } 65 /***************************************** 66 *根据条件考虑每个人,并调用错误统一处理函数 67 ******************************************/ 68 static void Select(const Condition *con) 69 { 70     char *presult; 71     if(con==NULL) 72         return; 73     if (NULL == (presult = new char[1024])) 74     { 75         exit(1); 76     } 77     switch(con->ngift) 78     { 79     case 0: 80         break; 81     case 1: 82         sprintf(presult,"fail:only have %s",con->pgift[1]); 83         throw MyException(1, presult); 84         break; 85     case 2: 86         sprintf(presult,"fail:only have %s,%s", con->pgift[0], con->pgift[5]); 87         throw MyException(2, presult); 88         break; 89     case 3: 90         sprintf(presult,"fail:only have %s,%s,%s",con->pgift[1], con->pgift[2], con->pgift[4]); 91         throw MyException(3, presult); 92         break; 93     default: 94         break; 95     } 96 } 97 char* MyException::Deal() const throw() 98 { 99     char *pstr = new char[1024];100     if (pstr == NULL)101         return NULL;102     if(m_ntype < 3)103         sprintf(pstr,"pass over:%s",m_str);104     else if(m_ntype < 5)105         sprintf(pstr,"just so so:%s",m_str);106     else107         sprintf(pstr,"wait and see:",m_str);108     return pstr;109 }

利用C++的try/catch/throw框架即可捕获异常,在把关的select函数中,我们有自定义的异常类MyException对象,将相关信息写进类中,然后抛出。在catch中捕获以后,调用类的Deal函数对异常进行统一处理。如果以后美女的想法改变,只有达到了5项条件的才算正常,那我们只需要修改Deal函数就可以了。

0 0