C++异常和错误处理经验谈

代替 try / catch / throw 的通常做法是返回一个返回代码(有时称为错误代码),例如,printf(), scanf() 和 malloc()就是这样工作的:调用者通过if等语句来测试返回值判断函数是否成功。

尽管返回代码技术有时是最适当的错误处理技术,但会增加不必要的if语句这样的令人讨厌的效果。

质量降级:众所周知,条件语句可能包含的错误大约十倍于其他类型的语句。因此,在其他都相同时,如果你能从代码中消除条件语句,你会得到更健壮的代码。

推迟面市:由于条件语句是分支点,而它们关系到白盒法测试时的测试条件的个数,因此不必要的条件语句会增加测试的时间总量。如果你没有走过每个分支点,那么你的代码中就会有在测试中没有被执行过的指令,直到用户/客户发现它,那就糟糕了。

增加开发成本:不必要的控制流程的复杂性增加了寻找bug,修复bug,和测试的工作。

因此,相对于通过返回代码和if来报告错误,使用try / catch / throw所产生更少有bug,更低的开发成本和更快面市的代码。

如何处理构造函数的失败?

构造函数没有返回类型,所以返回错误代码是不可能的。因此抛出异常是标记构造函数失败的最好方法。

如果你没有或者不愿意使用异常,这里有一种方法。如果构造函数失败了,构造函数可以把对象带入一种“僵尸”状态。你可以通过设置一个内部状态位使对象就象死了一样,即使从技术上来说,它仍然活着。然后加入一个查询(“检察员”)成员函数,以便类的用户能够通过检查这个“僵尸位”来确定对象是真的活着还是已经成为僵尸(也就是一个“活着的死对象”)。你也许想有另一个成员函数来检查这个僵尸位,并且当对象并不是真正活着的时候,执行一个 no-op(或者是更令人讨厌的如 abort())。这样做真的不漂亮,但是如果你不能(或者不想)使用异常的话,这是最好的方法了。

如何处理析构函数的失败?

往log文件中写一个消息。但不要抛出异常!

C++的规则是你绝对不可以在另一个异常的被称为“栈展开(stack unwinding)”的过程中时,从析构函数抛出异常。举例来说,如果某人写了throw Foo(),栈会被展开,以至throw Foo()和 } catch (Foo e) { 之间的所有的栈页面被弹出。这被称为栈展开(statck unwinding)

在栈展开时,栈页面中的所有的局部对象会被析构。如果那些析构函数之一抛出异常(假定它抛出一个Bar对象),C++运行时系统会处于无法决断的境遇:应该忽略Bar并且在} catch (Foo e) { 结束?应该忽略Foo并且寻找 } catch (Bar e) { ?没有好的答案——每个选择都会丢失信息。

因此C++语言担保,当处于这一点时,会调用terminate()来杀死进程。突然死亡。

防止这种情况的简单方法是不要从析构函数中抛出异常。但如果你真的要聪明一点,你可以说"当处理另一个异常的过程中时,不要从析构函数抛出异常"。但在第二种情况中,你处于困难的境地:析构函数本身既需要代码处理抛出异常,还需要处理一些“其他东西”,调用者没有当析构函数检测到错误时会发生什么的担保(可能抛出异常,也可能做一些“其他事情”)。因此完整的解决方案非常难写。因此索性就做一些“其他事情”。也就是,不要从析构函数中抛出异常。

当然,由于总有一些该规则无效的境况,这些话不应该被“引证”。但至少99%的情况下,这是一个好规则。

如果构造函数会抛出异常,我该怎样处理资源?

对象中的每个数据成员应该清理自己。

如果构造函数抛出异常,对象的析构函数将不会运行。如果你的对象需要撤销一些已经做了的动作(如分配了内存,打开了一个文件,或者锁定了某个信号量),这些需要被撤销的动作必须被对象内部的一个数据成员记住。

例如,应该将分配的内存赋给对象的一个“智能指针”成员对象Fred,而不是分配内存给未被初始化的Fred* 数据成员。这样当该智能指针消亡时,智能指针的析构函数将会删除Fred对象。标准类auto_ptr就是这种“智能指针”类的一个例子。你也可以写你自己的引用计数智能指针。

当别人抛出异常时,我如何改变字符数组的字符串长度来防止内存泄漏?

如果你要做的确实需要字符串,那么不要使用char数组,因为数组会带来麻烦。应该用一些类似字符串类的对象来代替。

时间: 2024-09-12 14:30:49

C++异常和错误处理经验谈的相关文章

JAVA中的异常与错误处理详解

  异常与错误: 异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发人员)已经犯了个错误,现在有一个机会来修改它.Java中使用异常类来表示异常,不同的异常类代表了不同的异常.但是在Java中所有的异常都有一个基类,叫做Exception. 错误: 它指的是一个合理的应用程序不能截获的严重的问题.大多数都是反常的情况.错误是VM的一个故障(虽然它可以是任何系统级的服务

java异常与错误处理基本知识_java

异常与错误:异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发人员)已经犯了个错误,现在有一个机会来修改它.Java中使用异常类来表示异常,不同的异常类代表了不同的异常.但是在Java中所有的异常都有一个基类,叫做Exception.错误:它指的是一个合理的应用程序不能截获的严重的问题.大多数都是反常的情况.错误是VM的一个故障(虽然它可以是任何系统级的服务).所以,

java-Java中PDF转图片报运行时异常,错误看不懂,求帮助

问题描述 Java中PDF转图片报运行时异常,错误看不懂,求帮助 下图是控制台报错信息,求大神帮忙看看,是PDF格式不支持吗? 解决方案 看下是不是你的页面太多,内存不够,需要调整jvm设置.

关于Java异常和错误的几个问题

1.Java中什么是Exception? 在java中,异常功能是通过实现比如Throwable,Exception,RuntimeException之类的类,然后还有一些处理异常时候的关键字,比如throw,throws,try,catch,finally之类的. 所有的异常都是通过Throwable衍生出来的.Throwable把错误进一步划分为 java.lang.Exception 和 java.lang.Error. java.lang.Error 用来处理系统错误,例如java.la

拦截PHP各种异常和错误,发生致命错误时进行报警,万事防患于未然

原文:拦截PHP各种异常和错误,发生致命错误时进行报警,万事防患于未然 在日常开发中,大多数人的做法是在开发环境时开启调试模式,在产品环境关闭调试模式.在开发的时候可以查看各种错误.异常,但是在线上就把错误显示的关闭. 上面的情形看似很科学,有人解释为这样很安全,别人看不到错误,以免泄露重要信息... 但是你有没有遇到这种情况,线下好好的,一上线却运行不起来也找不到原因... 一个脚本,跑了好长一段时间,一直没有问题,有一天突然中断了,然后了也没有任何记录都不造啥原因... 线上一个付款,别人明

深入探讨JAVA中的异常与错误处理_java

异常与错误: 异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发人员)已经犯了个错误,现在有一个机会来修改它.Java中使用异常类来表示异常,不同的异常类代表了不同的异常.但是在Java中所有的异常都有一个基类,叫做Exception. 错误: 它指的是一个合理的应用程序不能截获的严重的问题.大多数都是反常的情况.错误是VM的一个故障(虽然它可以是任何系统级的服务).

C#调用matlab混合编程时总是出现类型初始值设定项引发异常这种错误

问题描述 C#调用matlab混合编程时总是出现类型初始值设定项引发异常这种错误,请问该如何解决?matlab源码如下:function[y,z]=myadd2(a,b)%dummyfunction,justtodemonstratetheideay=a+b;z=a+2*b;endC#源码如下usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Dra

java异常和错误类总结(必看篇)_java

java异常和错误类总结 最近由于考试和以前的面试经常会遇到java当中异常类的继承层次的问题,弄得非常头大,因为java的异常实在是有点多,很难记下来,今天正好查了一些资料整理下来,希望对自己和大家有点帮助.最开始的时候习惯用笔记本(手写的纸质的本子)记笔记,后来发现查阅的时候不是很方便,而且速度比较慢.后来改用notepad开始记,感觉效果挺棒,简单易用,没有花哨的东西.但是也有它的缺点,比如版式的整理,不能加入一些图片(往往图片特别是一些大纲是非常好的记忆学习方法)等等,于是尝试用mark

深入探讨Java中的异常与错误处理

Java中的异常处理机制已经比较成熟,我们的Java程序到处充满了异常的可能,如果对这些异常不做预先的处理,那么将来程序崩溃就无从调试,很难找到异常所在的位置.本文将探讨一下Java中异常与错误的处理方法,一起来看看. 异常与错误: 异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发人员)已经犯了个错误,现在有一个机会来修改它.Java中使用异常类来表示异常,不同的异