C++ Primer 学习笔记与思考_11 try..catch语句及相关疑点
来源:互联网 发布:淘宝女鞋正品 编辑:程序博客网 时间:2024/06/13 14:00
在一个小的程序中,可以用比较简单的方法处理异常,例如用if语句判别除数是否为0,如果是0,则输出一个出错信息。但是在一个大的系统中,包含很多模块,每个模块又包含许多类和函数,函数之间又互相调用,比较复杂。如果在每一个函数中都设置处理异常的程序段,会使程序过于庞大和复杂。因此c++采用的办法是:如果在执行一个函数过程中出现异常,可以不在本函数中立即处理,而是发出一个信息,传给他的上一级(即调用他的函数),他的上机捕捉到这个信息后进行处理。如果上一级的函数也不能处理,就再传给上一级,如此逐级上送,如果还是不存在处理该异常的catch子句,程序的运行就要跳转到名为terminate的标准库函数,该函数在exception头文件中定义。这个标准库函数的行为依赖于系统,通常情况下,它的执行将导致程序非正常退出。
(一)基本语法结构
一般的catch出现的形式是:try{}catch(except1&){}catch(except2&){}catch(...){} //接受所有异常一般都写成引用(except1&),原因很简单,效率。简单的示例:
#include<iostream>#include<string>using namespace std;int main(){ string ex = "this is a exception"; try { cout<<"before throw"<<endl; throw ex; cout<<"after throw"<<endl; } catch(string &e) { cout<<e<<endl; } cout<<"end"<<endl;// }注意,catch中抛出string类型的异常后立即跳出此函数,随后被catch捕捉,执行catch处理后,继续执行catch后的语句,输出"end"。
(二)多个catch捕捉
一个try-catch结构中只能有一个rtry块,但是却可以有多个catch块,以便与不同的异常信息匹配。
int main(){ try { cout << "在 try block 中, 准备抛出一个异常." << endl; //这里抛出一个异常(其中异常对象的数据类型是char*) char* p=0; throw p; } //catch( char* value ) //注意这里catch语句 catch(...) { cout << "在 catch(…) block 中, char*类型的异常对象也被处理" << endl; }}catch还有另外一种写法,即除了指定类型名之外,还可以指定变量名,如catch(double d) { cout<<"throw "<<d<<endl; }
catch(...)删节号...代表他可以捕捉到任何类型的异常信息,通常放在try-catch结构的最后。
(三)嵌套的try-catch结构
int main() { try { //这里是嵌套的trycatch结构块 try { cout << "在 try block 中, 准备抛出一个int数据类型的异常." << endl; throw 1; } catch( double ) { cout << "在 catch block 中, double数据类型处理异常错误。"<< endl; } cout << "在 try block 中, 准备抛出一个int数据类型的异常." << endl; throw 0.5; } catch( int ) { cout << "在 catch block 中, int数据类型处理异常错误。"<< endl; } return 0; }抛出int异常后,要到上一层函数调用中才找到匹配的catch,因此只会输出最后一个catch中的处理数据。
[特别提示]:在C++标准中规定,可以在程序任何地方throw一个异常对象, 并不要求一定只能是在受到try block监控保护的作用域中才能抛出异常, 如果在程序中出现了抛出的找不到对应catch block的异常对象时,C++标准中规定要求系统必须执行terminate()来终止程序。 因此这个例程是可以编译通过的,但运行时却会异常终止。这往往给软件 系统带来了不安全性。与此形成对比的是java中提供的异常处理模型却是不允许出现这样的找不到对应catch block的异常对象,它在编译时就给出错误 ,所以java中提供的异常处理模型往往比C++要更完善。
try-catch的问题解决了,我们再来看一下我在c++ primer的语句这一章找到的两个知识点:
1.悬垂else问题
int main(){int a=0,b=0;if(a<=b) if(a==b) a++;elseb++;cout<<a<<" "<<b<<endl;return 0; }
这个程序表明了所有语言的if语句都普遍存在着潜在的二义性。这种情况往往成为悬垂else问题;上述代码中,看缩进的用法表明else应与外层的if语句相匹配。然而,C++中解决悬垂else问题的二义性的办法 是通过将else匹配给最后出现的尚未匹配的if子句来解决。
所以相当于第一个if的处理是空语句。
2.简洁就是美while语句内部数组复制的简洁代码 int arr1[10]; int *source=arr1; size_t sz=sizeof(arr1)/sizeof(*arr1); int *dest=new int[sz]; while(source!=arr1+sz) *dest++=*source++; //简洁,相当于/* *dest=*source; ++dest; ++source; */
可以在for语句的init-statement中定义多个对象,但是不管怎样,该处只能出现一个语句,因此所有的对象必须具有相同的一般类型
for(int ival=0,*pi=ia,&ri=val;ival!=size;++ival,++pi,++ri)
{} //必须都为int类型
- C++ Primer 学习笔记与思考_11 try..catch语句及相关疑点
- C++ Primer 学习笔记_20_语句(续) --break/continue/try,catch
- 黑马程序员_文件IO流部分疑点和JDK1.7版本后新try-catch处理学习笔记
- [初学笔记] try...catch...end语句
- try...catch...效率思考
- try-catch使用思考
- 关于if语句,关于try-catch不得不说的思考
- c++Primer学习笔记(5)--语句
- c++primer学习笔记(6.0)语句
- C++Primer学习笔记(6)语句
- C++primer学习笔记-第六章语句
- C++primer学习笔记-----5.3条件语句
- Java学习笔记_11
- JavaScript Try...Catch 语句
- JavaScript Try...Catch 语句
- try-catch语句
- JavaScript Try...Catch 语句
- JavaScript Try...Catch 语句
- leetcode283 : Move Zeroes
- 地图的使用(定位)
- 如果要查找%'或'_',则需要使用关键字ESCAPE定义一个转义符号
- MVC3 Html.DropDownList使用方法总结
- OpenGL几何变换
- C++ Primer 学习笔记与思考_11 try..catch语句及相关疑点
- S-functions
- 折腾CentOS--让linux启动后自动进入图形界面或文本界面
- 死锁
- Log4j的基本使用
- 网络层其它协议,转载自实验楼
- HDU 3374 String Problem(最大最小表示法 模板题)
- 自定义控件
- 搬家了(http://13kv.com/)