[转] C++ try catch() throw 异常处理
其它很多程序员一样,本书的主人公阿愚也是在初学C++时,在C++的sample代码中与异常处理的编程方法初次邂逅的,如下: try // Other normal program statements 瞧瞧,代码看上去显得那么整齐、干净,try block和catch block遥相呼应,多有对称美呀!因此主人公初次见面后就一见钟情了。 为什么要选用异常处理的编程方法? void main(int argc, char* argv[]) } 因为程序的执行过程中总会遇到许多可预知或不可预知的错误事件,例如说,由于内存资源有限导致需要分配的内存失败了;或某个目录下本应存在的一个文件 但C++中的异常处理的机制彻底改变了这种面貌,它使真正的计算处理和错误处理分开来,让程序员不再被这些琐碎的事情所烦扰,能关注于真正的计算处理工作。同时代码的可读性也好了。因此我们有理由选择异常处理的编程方法。具体原因如下: 相信绝大多数程序员都知道C++中的异常处理的编程方法,可还是有很多人已习惯原来单纯的面向过程的代码组织方式,不太习惯或较少使用 如果您喜欢玩一款游戏,您必须先要很好理解这款游戏的规则。同样主人公阿愚喜欢上C++中异常处理后,当然也首先关注它的游戏规则,这就是C++中异常处理的语法。
关键字 1、 try 语法 1、还是给一个例子吧!如下: int main() //定义一个try block,它是用一对花括号{}所括起来的块作用域的代码块 //这里抛出一个异常(其中异常对象的数据类型是int,值为1) cout << "在 try block 中, 由于前面抛出了一个异常,因此这里的代码是不会得以执行到的" << endl; cout << "Back in main. Execution resumes here." << endl; } 2、语法很简单吧!的确如此。另外一个try block可以有多个对应的catch block,可为什么要多个catch block呢?这是因 int main() cout << "在 try block 中, 准备抛出一个double数据类型的异常." << endl; return 0; 3、一个函数中可以有多个trycatch结构块,例子如下: int main() //这里是二个trycatch结构块,当然也可以有第三、第四个,甚至更多 return 0; 4、
上面提到一个try block可以有多个对应的catch block,这样便于不同的异常错误分类处理,其实这只是异常错误分类处理的方法之一(暂且 把它叫做横向展开的吧!)。另外还有一种就是纵向的,也即是分层的、trycatch块是可以嵌套的,当在低层的trycatch结构块中不能匹配到相同 类型的catch block时,它就会到上层的trycatch块中去寻找匹配到正确的catch block异常处理模块。例程如下: int main() cout << "在 try block 中, 准备抛出一个double数据类型的异常." << endl; return 0; 5、讲到是trycatch块是可以嵌套分层的,并且通过异常对象的数据类型来进行匹配,以找到正确的catch block异常错误处理代码。这里就不得不详细叙述一下通过异常对象的数据类型来进行匹配找到正确的catch block的过程。 (1) 首先在抛出异常的trycatch块中查找catch block,按顺序先是与第一个catch block块匹配,如果抛出的异常对象的 (2) 如果有二个或更多的catch block,则继续查找匹配第二个、第三个,乃至最后一个catch block,如匹配成功,则进入到对应的catch block中执行;否则到三步; (3) 返回到上一级的trycatch块中,按规则继续查找对应的catch block。如果找到,进入到对应的catch block中执行;否则到四步; (4) 再到上上级的trycatch块中,如此不断递归,直到匹配到顶级的trycatch块中的最后一个catch block,如果找到,进入到对应的catch block中执行;否则程序将会执行terminate()退出。 另外分层嵌套的trycatch块是可以跨越函数作用域的,例程如下: void Func() throw() int main() cout << "在 try block 中, 准备抛出一个double数据类型的异常." << endl; throw 0.5;
} catch( double& d_value ) { cout << "在 catch block 中, double数据类型处理异常错误。”<< endl; } catch( int& value ) { //这个例子中,Func()函数中抛出的异常会在此被处理 cout << "在 catch block 中, int数据类型处理异常错误。”<< endl; } return 0; 6、刚才提到,嵌套的trycatch块是可以跨越函数作用域的,其实这里面还有另外一层涵义,就是抛出异常对象的函数中并不一定必须存在 void Func() throw() int main() cout << "在 try block 中, 准备抛出一个double数据类型的异常." << endl; //如果这里调用这个函数,那么由于main()已经是调用栈的顶层函数,因此不能找 ///////////////////////////////////////////////////
为什么要用catch(…)这个东东?
程序员朋友们也许会说,这还有问吗?这篇文章的一开始不就讲到了吗?catch(…)能够捕获多种数据类型的异常对象,所以它提供给程序员一种对异常 void Func() 还有,特别是VC程序员为了使开发的系统有更好的可靠性,往往在应用程序的入口函数中(如MFC框架的开发环境下 BOOL CXXXApp::InitInstance() AfxEnableControlContainer(); // Standard initialization #ifdef _AFXDLL // 注意这里有一个顶层的trycatch块,并且使用catch(…)来捕获一切所有的异常 // Since the dialog has been closed, return FALSE so that we exit the 通过上面的例程和分析可以得出,由于catch(…)能够捕获所有数据类型的异常对象,所以在恰当的地方使用catch(…)确实可以使软件系统有着 从上面的异常分类来看,它有明显的层次性和继承性,这恰恰和面向对象的继承思想如出一辙,因此用对象来描述程序中出现的异常是再恰当不过的了。而且可以利用面向对象的特性很好的对异常进行分类处理,例如有这样一个例子:
void OpenFile(string f) void ReadFile(File f) void WriteFile(File f) void Func() ReadFile(…); WriteFile(…); 通过上面简单的例子可以看出,利用面向对象的方法,确实能很好地对异常进行分类处理,分层处理,如果异常能得以恢复的尽可能去实现恢复,否则向上层重 现在回想一下上一篇文章中提出的那个问题?就是既然有其它很好的方法(利用类的继承性)来可以代替catch(…)提供的异常集中处理,那为什么 异常处理中采用面向对象技术还有哪些好处呢? 上面讲到,用对象来描述程序中出现的异常除了能很好地分层处理异常外,还有那些好处呢?当然除了好处大大的外,好处也是多多的,例如: (1) 面向对象的实现中,一般都很好的实现了对象的RTTI技术,如果异常用对象来表示,那么就可以很好完成异常对象的数据类型匹配,还有就是函数 (2) 面向对象的实现中,一般都很好的实现了对象的构造、对象的销毁、对象的转存复制等等,所以这也为异常处理模型中,异常对象的转存复制和对象销毁提供了很好的支持,容易控制; 在异常处理的分层管理下,异常对象的重新抛出往往非常常见,本文中刚才的例子就有这样的情况,但当时仅一笔带过而已,为了表明对它的重视,下一篇文章重点讨论一下异常对象的rethrow处理。 |
[转] C++ try catch() throw 异常处理的更多相关文章
- 异常处理(try catch throw)详解(C++)
选择异常处理的编程方法的具体原因如下: 1.把错误处理和真正的工作分开来: 2.代码更易组织,更清晰,复杂的工作任务更容易实现: 3.毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了: 4 ...
- Ruby跳出多层循环 catch...throw
在编码的时候,有时候会遇到嵌套循环的情况,最内部的循环结束的时候,想跳出所有循环,这个时候我们往往采用通过内部循环设置一个flag来控制外部跳出循环条件,比如: #encoding:utf-8 for ...
- (六)JavaScript之[Regular Expression]与[错误(try, catch, throw)]
10].正则表达式 /** * 正则表达式(Regular Expression): * * 用于文本搜索和文本替换 * */ /** * /good/i是一个正则表达式. * good是一个模式(用 ...
- js学习笔记2:循环和try/catch/throw
今天学习了js的比较.if/else.switch/case和各种循环,这些东西每种语言都大同小异,没什么好看的,重点说一下js的循环. JavaScript 支持不同类型的循环: for - 循环代 ...
- C++异常处理:try,catch,throw,finally的用法
写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...
- C++异常处理: try,catch,throw,finally的用法
写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...
- C++ 异常处理(try catch throw)、命名空间
一.c++工具 模板(函数模板.类模板).异常处理.命名空间等功能是c++编译器的功能,语言本身不自带,这些功能已经成为ANSI C++标准了,建议所有的编译器都带这些功能,早期的c++是没有这些功能 ...
- 22 C#中的异常处理入门 try catch throw
软件运行过程中,如果出现了软件正常运行不应该出现的情况,软件就出现了异常.这时候我们需要去处理这些异常.或者让程序终止,避免出现更严重的错误.或者提示用户进行某些更改让程序可以继续运行下去. C#编程 ...
- C++异常处理(try catch throw)完全攻略
程序运行时常会碰到一些异常情况,例如: 做除法的时候除数为 0: 用户输入年龄时输入了一个负数: 用 new 运算符动态分配空间时,空间不够导致无法分配: 访问数组元素时,下标越界:打开文件读取时,文 ...
随机推荐
- Javadoc注释的用法
Javadoc注释的用法 相关阅读:http://blog.163.com/hui_san/blog/static/5710286720104191100389/ Java 文档// 注释一行/* ...
- bzoj1036: [ZJOI2008]树的统计Count link-cut-tree版
题目传送门 这 算是link-cut-tree裸题啊 不过以前好像没有写过单点修改.............. #include<cstdio> #include<cstring&g ...
- LeetCode 4 :Majority Element
problem:Given an array of size n, find the majority element. The majority element is the element tha ...
- 【反演复习计划】【COGS2431】爱蜜莉雅的求助
出题人怎么这么不认真啊==明明官方译名是爱蜜莉雅…… 而且我们爱蜜莉雅碳是有英文名哒!是Emilia.你那个aimiliya我实在是无力吐槽…… 不过抱图跑23333首先这很像约数个数和函数诶!但是唯 ...
- python数据类型-----字符串
今天来总结下python3.4版本字符串的一些操作方法,对这些方法先作一个简单的分类,按照分类来进行总结. Sequence Typessequence类型有六种:strings, byte sequ ...
- KDJ金叉测试
# -*- coding: utf-8 -*- import os import pandas as pd # ========== 遍历数据文件夹中所有股票文件的文件名,得到股票代码列表stock_ ...
- [BZOJ1227][SDOI2009]虔诚的墓主人 组合数+树状数组
1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec Memory Limit: 259 MBSubmit: 1433 Solved: 672[Submit][Stat ...
- [BZOJ2064]分裂 状压dp
2064: 分裂 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 656 Solved: 404[Submit][Status][Discuss] De ...
- zoj3256
好题,由m的范围知道这肯定是矩阵乘法加速插头dp,关键是怎么写 以往插头dp常用逐格递推,而这道题要求整行逐列递推 这样我们才能构造转移矩阵. 我们可以通过假象一个第0列来将路径转化为回路问题 逐列递 ...
- Ubuntu 16.04下开启Mysql 3306端口远程访问
原文地址:传送门 0. 前言 网上看到很多开启Mysql远程访问端口,修改的配置文件我都没有找到. 特意查看了我的Linux版本 $ sudo lsb_release -a 显示如下: Distrib ...