关于c++中的异常处理使用方法与技巧

关于c++中的异常处理使用方法与技巧

ID:32677155

大小:69.19 KB

页数:7页

时间:2019-02-14

关于c++中的异常处理使用方法与技巧_第1页
关于c++中的异常处理使用方法与技巧_第2页
关于c++中的异常处理使用方法与技巧_第3页
关于c++中的异常处理使用方法与技巧_第4页
关于c++中的异常处理使用方法与技巧_第5页
资源描述:

《关于c++中的异常处理使用方法与技巧》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、1关于异常处理1.1为什么要抛出异常拋出异常的好处一是可以不干扰正常的返回值,另一个是调用者必须处理异常,而不像以前C语言返回一个整数型的错误码,调用者往往将它忽略了。C++的异常处理确保当程序的执行流程离开一个作用域的时候,对于属于这个作用域的所有由构造函数建立起来的对象,它们的析构函数一定会被调用。1.2捕获所有异常有时候,程序员可能希望创建一个异常处理器,使其能够捕获所有类型的异常。用省略号彳弋替异常处理器的参数列表就可以实现这一点:catch(…){cout<<"anexceptionwasthrown**<

2、cateyourresourceheretandthenrethrowthrow;}由于省略号异常处理器能够捕获田可类型的异常所以最好将它放在异常处理器列表的最后,从而避免架空它后面的异常处理器。省略号异常处理器不允许接受任何参数,所以无法得到任何有关异常的信息,也无法知道异常的类型。它是一个“全能捕获者”。这种8tCh子句经常用于清理资源并重新抛出所捕获的异常。1.3重新抛出异常当需要释放某些资源时,例如网络连接或位于堆上的内存需要释放时,通常希望重新抛出一个异常。(详见本章后面的“资源管理”一节。)如果发生了异常,读者不必关心到底是什么错误

3、导致了异常的发生——只需要关闭以前打开的一个连接。此后,读者希望在某些更接近用户的语境(也就是说,在调用链中的更高层次)中对异常进行处理。在这种情况下,省略号异常处理器正符合这种的要求。这种处理方法,可以捕获所有异常,清理相关资源,然后重新抛出该异常,以使得其他地方的异常处理器能够处理该异常。在一个异常处理器内部,使用不带参数的throw®句可以重新抛出异常:catch(...){cout<<"anexceptionwasthrown"<

4、;}与同一个try块相关的随后的8tch子句仍然会被忽略一"row子句把这个异常传递给位于更高一层语境中的异常处理器。另外,这个异常对象的所有信息都会保留,所以位于更高层语境中的捕获特定类型异常的异常处理器能够获取这个对象包含的所有信息。1.4构造函数中的异常C++规定构造函数拋出异常之后,对象将不被创建,析构函数也不会被执行,但已经创建成功的部分(比如一个类成员变量)会被部分逆序析构,不会产生内存泄漏。但有些资源需要在抛出异常前自己清理掉,比如打开成功的一个文件,最好关闭掉再拋岀异常(虽然系统也会把这个资源回收),因为抛岀异常之后析构函数不会

5、被执行了。(1)C++中通知对象构造失败的唯一方法那就是在构造函数中抛出异常;(这句话并不是说我们只有这个方法才能让上层知道构造函数失败,虽然构造函数没有返回值,我们完全可以在构造函数中传入一个引用值,然后在里面设置状态,运行完构造函数之后任然可以知道是否失败但这种情况下面对象其实还是被构造出来的只是里面有资源分配失败而已,并且析构函数还是会执行。这和我们构造失败不生成对象的初衷不符。)(2)构造函数中抛出异常将导致对象的析构函数不被执行;(但已经生产的部分成员变量还是会被逆向析构的)(3)当对象发生部分构造时,已经构造完毕的子对象将会逆序地被

6、析构;对于构造函数可能失败的做法一般有两种1.在构造函数中抛出异常,本对象构造未完成,它的析构函数不会被调用。当然,我们有义务释放已经分配到的资源。简单,最常见。2.把资源的初始化工作放在另一个单独函数中,比如boolinit(...),由对象创建者(比如工厂方法)先调用构造函数,再调用init方法。ATL中常见。1.5析构函数中的异常C++标准指明析构函数不能、也不应该抛岀异常。在析构函数中抛出错误,通常被认为象征着拙劣的设计或糟糕的编码。这是因为:析构函数如果抛出异常,将会导致调用标准库terminate函数,而terminate函数将调用

7、abort函数,导致程序的非正常退出。所以析构函数应该从不抛出异常。析构函数不能抛岀异常的理由:1)如果析构函数抛出异常,则异常点之后的程序不会执行,如果析构函数在异常点之后执行了某些必要的动作比如释放某些资源,则这些动作不会执行,会造成资源泄漏。2)通常异常发生时,C++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数本身也抛出异常,则前一个异常尚未处理,又有新的异常,会造成程序崩溃。那么当无法保证在析构函数中不发生异常时,该怎么办?其实还是有很好办法来解决的。那就是把异常完全封装在析构函数内部,决不让异常抛出函数之外。这是一种非

8、常简单,也非常有效的方法。~ClassName()try{do_something();}catch(...){〃这里可以什么都不做,只是保证catc

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。