当前位置:天才代写 > tutorial > C语言/C++ 教程 > 用C++异常代替exit()函数

用C++异常代替exit()函数

2017-11-05 08:00 星期日 所属: C语言/C++ 教程 浏览:731

副标题#e#

从C语言开始打仗C++的人,恐怕都知道exit()这个函数,好像此刻许多的措施员都有这样一种习惯,在措施一碰着错误、或任务刚完成时,把挪用exit()函数当成是一种最好的竣事措施的要领。在以前遗留的很多老式C/C++代码中,这种现象很是普遍,但当手头的软件项目慢慢希望并越来越大时,就不得不面对归并以前分手的各个模块这项事情,此时,假如尚有人记得起软件日志记录、错误宽容度、或至少适当的清理事情,就已经是万幸了。本文中要说的要领,决不是一条设计准则,可是可减轻批改那些未精采设计及实现的老式代码时所带来的疾苦。

用return来代替exit,无疑是办理此问题最显而易见的要领,假如软件项目很是简朴,这也是最高效的办理方案;然而,项目中常常有成打的函数漫衍在多个源文件中,且这些函数的挪用也嵌套在很深的条理中,那么,工作就变得棘手了。假如在这种环境中,所有的函数都返回void,照旧有大概修改它们,让其返回一个退出码(exit code)的,但所支付的价钱也很大;假如函数已经能返回一个有意义的值,只是在碰着错误时,挪用了exit(),那么这项事情会变得更耗损时间,也会越发容易堕落。这里说点题外话,利用exit()也是有可取之处的,当老式代码没有设计返回任何对象时,假如想获得返回码(return code),只有靠exit()了。

有关此问题,照旧有一个办理要领的,在这种环境下,我们假定所有的源代码已经为C++名目,或无需全部编译就可以移植为C++名目,把所有exit呈现的处所全部换成throw(这可以自动完成,甚至无须领略老代码是奈何事情的);接着,在任何适当的处所,捕获为整数的异常码,这种要领还可依据严重性或规复水平的差异,在差异层面上处理惩罚错误。

请看以下示例,原始代码如下:

// main.cpp
void main() {
 //初始化
 ...
 ProcessMail(...);
}
//另一个源文件
void ProcessMail(...) {
 //初始化
 ...
 if ( initializationError ) {
  printf("faild to init!!!\n");
  exit(-1);
 }
 while ( !shutdown ) {
  ReadMail(...)
  //继承处理惩罚
  ...
 }
}
void ReadMail(...)
{
 ...
 //对ReadBytes()的挪用呈此刻函数内的多处处所,包罗在轮回中。
 nBytesAvailable = ReadBytes(...)
 ...
}
//另一个源文件
int ReadBytes(...)
{
 //读取数据
 ...
 if ( error ) {
  printf("there was an error!!\n");
  exit(-1);
 }
 return nBytesRead;
}


#p#副标题#e#

在原始代码中缺少规复或日志记录的成果,假如产生了一个错误,措施就会"消失"不见了,让用户手足无措。下面是从头组织后的代码,留意,没有修改函数修饰符:

void main() {
 //初始化
 ...
 try {
  ProcessMail(...);
 } catch (int ret) {
  switch (ret) {
   case E_INITIALIZATION_FAILURE: ...
   case E_IRRECOVERABLE: ...
   ...
  }
 }
}
void ProcessMail(...) {
 //初始化
 ...
 if ( initializationError ) {
  throw(E_INITIALIZATION_FAILURE);
 }
 while ( !shutdown ) {
  try {
   ReadMail(...)
  } catch (int ret) {
   switch (ret) {
    case E_READ_ERROR:
     //记录错误信息
     ...
     //试图规复
     ...
     if ( recovered ) {
      continue;
     } else {
      throw(E_IRRECOVERABLE);
     }
     break;
    case ...
   }
  }
  //继承处理惩罚
  ...
 }
 //throw()可以用来代替缺少的返回码
 //但也要留意由此带来的机能损失
 throw(S_OK);
} // ProcessMail()
void ReadMail(...)
{
 ...
 //在此无须捕获异常
 nBytesAvailable = ReadBytes(...)
 ...
}
int ReadBytes(...)
{
 //读取数据
 if ( error ) {
  throw(E_READ_ERROR);
 }
 return nBytesRead;
}

此刻,修改以前遗留的老式项目时,是不是多点信心了呢?

 

    关键字:

天才代写-代写联系方式