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

从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;
}

时间: 2025-01-30 14:54:42

用C++异常取代exit()函数的相关文章

重构——55以异常取代错误码(Replace Error Code with Exception)

以异常取代错误码(Replace Error Code with Exception) 某个函数返回一个特定的错误码,用以表示某种错误情况:改用异常 一.动机 代码的可理解性使我们虔诚追求的目标 二.做法 1.决定应该抛出受控异常还是非受控异常 2.如果调用者有责任在调用前检查必要状态,就抛出非受控异常 3.找到该函数的所有调用者,对它们进行相应调整,让它们使用异常 4.修改该函数的签名,令它反映出新用法

Linux多任务编程(四) exit()函数及其基础实验

exit()和_exit()函数 函数说明 创建进程使用fork()函数,执行进程使用exec函数族,终止 进程则使用exit()和_exit()函数.当进程执行到exit()或_exit()函数时,进程会无条件的停止剩下的所有操 作,清除各种数据结构,并终止本进程的运行.但是,这两个函数还是有区别的,其调用过程如图1所示: 从图1可以看出,_exit()函数的作用是:直接使进程停止运行,清除其使用的内存空间,并清除其 在内核中的各种数据结构:而exit()函数则在这些基础上做了一些包装,在执行

_exit()函数与exit()函数的区别

exit()在结束调用它的进程之前,要进行如下步骤: 1.cleanup(): 2.在atexit()注册的函数: 'exit()'与'_exit()'有不少区别在使用'fork()',特别是'vfork()'时变得很 突出. 'exit()'与'_exit()'的基本区别在于前一个调用实施与调用库里用户状态结构 (user-mode constructs)有关的清除工作(clean-up),而且调用用户自定义的清除程序 (译者注:自定义清除程序由atexit函数定义,可定义多次,并以倒序执行)

了解Powershell中的Exit函数_PowerShell

Powershell支持"EXIT"关键字,它的范围是基于作用域的,它可能比你想象的工作方式要不同. 让我们来测试下这个函数: 复制代码 代码如下: function test {   'A'   exit   'B' } 当你保存并调用脚本,你将得到: 复制代码 代码如下: PS> C:\Users\Tobias\Documents\PowerShell\test12343.ps1 A 这时"exit"过早的结束了这个函数.可是当你没有保存当前脚本或当你调用

C++ WIN32控制台异常关闭回调函数

/* This is an example of the SetConsoleCtrlHandler function that is used to install a control handler. When a CTRL+C signal is received, the control handler returns TRUE, indicating that it has handled the signal. Doing this prevents other control ha

《Effective C++》item25:考虑写出一个不抛异常的swap函数

 std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _TCHAR* argv[]) { int a[10] = {1,2,3,4,5,6,7,8,9,10}; vector<int> vec1(a, a + 4); vector<int> vec2(a + 5, a + 10); swap(vec1, vec2); for (int i

C++函数专题

局部变量的作用域-多线程和函数里的静态变量 关于C++类成员函数的重载.覆盖.隐藏与virtual关键字 在C++中使用Lambda函数提高代码性能 关于拷贝构造函数和赋值运算符 析构函数的奥秘 C++中强制转换函数总结 C++中的延时函数 C++中的类静态成员和静态成员函数 c与c++中的time相关函数 C++空类的默认成员函数总结 C++指针探讨(四)函数对象 C++指针探讨(三)成员函数指针 C++指针探讨(二)函数指针 C++回调函数用法 vcl库函数 在Delphi与C++之间实现函

linux中exit()和_exit()函数的作用

exit和_exit函数都是用来终止进程的.当程序执行到exit或_exit时,系统无条件的停止剩下所有操作, 清除包括PCB在内的各种数据结构,并终止本进程的运行.但是,这两个函数是有区别的. exit()函数的作用是:直接使用进程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据 结构:_exit()函数则在这一基础上做了一些包装.在执行退出之前加了若干道工序.exit()函数与_exit()函 数最大区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区

VB.net 在64位win7系统下,调用API函数,在传址时为什么总会发生异常。。

问题描述 请帮教各位高人,VB.net在64位win7系统下,调用API函数,在传址时为什么总会发生异常..函数声明:DeclareSubdmc_move_line3Lib"DMC.dll"(ByRefaxisAsShort,ByValDist1AsInteger,ByValDist2AsInteger,ByValDist3AsInteger,ByValposi_modeAsShort)函数调用:DimAxisArray(3)AsShortDimLineEndArray(3)AsInt