首页 / C++ / 第65课 C++中的异常处理(下)
第65课 C++中的异常处理(下)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了第65课 C++中的异常处理(下),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2643字,纯文字阅读大概需要4分钟。
内容图文
1. C++中的异常处理
(1)catch语句块可以抛出异常
①catch中获捕的异常可以被重新抛出
②抛出的异常需要外层的try-catch块来捕获
③catch(…)块中抛异常的方法是throw;也是将所有异常重新抛出
(2)catch块中重新抛异常的意义
①可以被外层try-catch块捕获,并重新解释异常的信息。
②工程开发中使用这样的方式统一异常类型
A.假设我们的私有库使用到了第3方的库函数,如func。
B.但其抛出的异常类型为int*类型,很不友好。我们可以在私有库使用func的地方捕获这个异常,并在catch块中重新解释这个异常并抛出为我们自定义的Exception类型.
【编程实验】异常的重新解释
#include <iostream> usingnamespace std; //演示在catch块中可以抛出异常void Demo() { try { try { throw‘c‘; } catch(int i) { cout << "Inner:catch(int i)" << endl; throw i; //重新抛出异常 } catch(...) { cout << "Inner:catch(...)" << endl; throw; //抛出所有类型的异常 } }catch(...) { cout << "Outer:catch(...)" << endl; } } /* 假设:当前的函数是第三方库中的函数。因此,我们无法修改源代码 函数名: void func(int i) 抛出异常的类型:int -1 ==> 参数异常 -2 ==> 运行异常 -3 ==> 超时异常 */void func(int i) { if ( i < 0 ) { throw -1; } if ( i > 100 ) { throw -2; } if ( i == 11) { throw -3; } //正常运时时 cout << "Call func(int i)" << endl; } //以下是我们的私有库,当中使用到了第3方的库,这里需要将第3方库的 //异常类型统一成我们的异常信息格式void MyFunc( int i) { try { func(i); } catch(int i) { switch(i) { case -1: throw"Invalid Parameter"; break; case -2: throw"Runtime Exception"; break; case -3: throw"Timeout Exception"; break; } } } int main() { Demo(); cout << endl; try { MyFunc(11); } catch(constchar* cs) { cout << "Exception info: " << cs << endl; } return0; }; /*输出结果: Inner:catch(...) Outer:catch(...) Exception info: Timeout Exception */
2. 自定义异常类类型
(1)对于类类型异常的匹配依旧是至上而下严格匹配
(2)赋值兼容性原则在异常匹配中依然适用,因此一般而言:
①匹配子类异常的catch放在上部
②匹配父类异常的catch放在下部(否则如果放上面,则子类异常由于赋值兼容会被父类捕获)。
(3)工程中会定义一系列的异常类,每个类代表可能出现的一种异常类型。
(4)代码复用时可能需要重解释不同的异常类(如由于继承的层次关系,很可能父类的异常类在子类中会被重新解释)
(5)在定义catch语句块时推荐使用引用作为参数
【编程实验】类类型的异常
3.C++标准库中提供的异常类族
(1)标准库(#include <stdexcept>)中的异常都是从exception类派生的
(2)exception类有两个主要的分支
①logic_error:常用于程序中的可避免的逻辑错误
②runtime_error:常用于程序中无法避免的恶性错误
(3)标准库中的异常
【编程实验】标准库中的异常使用
4. C++异常机制中没提供finally块解决方案
(1)RAII技术(Resource Aquisition Is Initialization,资源获得即初始化)
①基本的思路:通过一个局部对象来表现资源,于是局部对象的析构函数将会释放资源。即,将资源封装成一个类,将资源的初始化封装在构造函数里,释放封装在析构函数里。要使用资源的时候,就实例化一个局部对象。
②在抛出异常的时候,由于局部对象脱离了作用域,自动调用析构函数,会保证资源被释放。
(2)具体做法
①直接使用局部变量。
try { File f( " xxx.ttt "); //使用局部对象 //其他操作 } //异常发生时和正常情况下,文件资源都在这里被释放catch { //... }
②将资源封装在一个类中
class Test{ public : File *file;//资源被封装起来 Test() { file = new file(...); } ~Test() { delete file;} }; try{ Test t; //使用局部对象 //其他操作 } //无论什么情况下,t在这里被释放,同时调用析构函数catch { //... }
③使用智能指针
try { std::auto_ptr<file> pfile = new file(); //.... } //无论什么情况,智能指针都在这里被释放catch(...) { //.... }
5. 小结
(1)catch语句块中可以抛出异常
(2)异常的类型可以是自定义类类型
(3)赋值兼容性原则在异常匹配中依然适用
(4)标准库中的异常都是从exception类派生的。
原文:http://www.cnblogs.com/5iedu/p/5654806.html
内容总结
以上是互联网集市为您收集整理的第65课 C++中的异常处理(下)全部内容,希望文章能够帮你解决第65课 C++中的异常处理(下)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。