admin 管理员组

文章数量: 1184232


2024年3月19日发(作者:vectorjava用法)

这两天要处理一个异常的问题,刚好查了些相关的资料。在网上看到了一个不错的贴

子,就转了过来,方便本人,以及来此旅游的朋友学习。源地址:

/?91983,1

异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制。

也 许我们已经使用过异常,但是你会是一种习惯吗,不要老是想着当我打开一个文

件的时候才用异常判断一下,我知道对你来说你喜欢用return value或者是print

error message来做,你想过这样做会导致Memory Leak,系统退出,代码重复/

难读,垃圾一堆…..吗?现在的软件已经是n*365*24小时的运行了,软件的健壮已

经是一个很要考虑的时候了。

自序:

对写程序来说异常真的是很重要,一个稳健的代码不是靠返回Error

Message/return Value来解决的,可是往往我们从C走过来,习惯了这样的方式。

仅 以本文献给今天将要来临的流星雨把,还好我能在今天白天把这写完,否则会是

第4个通宵了;同时感谢Jeffrey大师,没有他的SEH理论这篇文章只能完 成一半,

而且所有SEH列子的构想都来自他的指导;另外要感谢Scott Meyers大师,我是

看他的书长大的;还要感谢Adamc / Darwin / Julian ,当然还有Nick的Coffee

内容导读:

(请打开文档结构图来读这篇文章。)

本文包括2个大的异常实现概念:C++的标准异常和SHE异常。

C++ 标准异常:也许我们了解过他,但你有考虑过,其实你根本不会使用,你不相

信,那我问你:垃圾回收在C++中怎么实现?其实不需要实现,C++已经有了,但

是你不会用,那么从<构造和析构中的异常抛出>开始看把。也许很高兴看到错误之

后的Heap/Stack中对象被释放,可是如果没有呢?有或 者试想一下一个能解决的

错误,需要我们把整个程序Kill掉吗?

在C++标准异常中我向你推荐这几章:<使用异常规格编程> <构造和

析构中的异常抛出> <使用析构函数防止资源泄漏> 以及一个深点的<抛出一个异

常的行为>

SHE异常: 我要问你你是一个WIN32程序员吗?如果不是,那么也许你真的不需

要看

这 块内容了,SHE是Windows的结构化异常,每一个WIN32程序员都应该要掌

握它。SHE功能强大,包括Termination handling和Exception handling两大

部分,强有力的维护了代码的健壮,虽然要以部分系统性能做牺牲(其实可以避免)。

在SHE中有大量的代码,已经在Win平台上测试过 了。

这里要提一下:在__finally处理中编译器参与了绝大多数的工作,而Exception则

是OS接管了几乎所有的工作,也许我没有提到 的是:对__finally来说当遇到

ExitThread/ExitProcess/abort等函数时,finally块不会被执行。另,我们的代码

使用软件异常是比return error message好2**32的方法。

另, 《使用析构函数防止资源泄漏》这个节点引用了More effective C++的条款9,

用2个列子,讲述了我们一般都会犯下的错误,往往这种错误是我们没有意识到的但

确实是会给我们的软件带来致命的Leak/Crash,但 这是有解决的方法的,那就是

使用―灵巧指针‖。

如果对照的37条条款,关于异常的高级使用,有以下内容

是没有完成的:

l 使用构造函数防止资源Leak(More effective C++ #10)

l 禁止异常信息传递到析构Function外 (More effective C++ #11)

l 通过引用捕获异常 (More effective C++ #13)

l 谨慎使用异常规格 (More effective C++ #14)

l 了解异常处理造成的系统开销 (More effective C++ #15)

l 限制对象数量 (More effective C++ #26)

l 灵巧指针 (More effective C++ #28)

[声明:节点:<使用析构函数防止资源泄漏> 和 节点:<抛出一个异常的行为>中

有大量的关于More effective C++的条款,所以本文挡只用于自我阅读和内部交流,

任何公开化和商业化,事先声明与本人无关。]

C++异常

C++引入异常的原因

C++ 新增的异常机制改变了某些事情,这些改变是彻底的,但这些改变也可能让我

们不舒服。例如使用未经处理的pointer变的很危 险,Memory/Resource Leak

变的更有可能了(别说什么Memory便宜了,那不是一个优秀的程序员说的话。),

写出一个具有你希望的行为的构造函数和析构函数也变的困难(不 可预测),当然

最危险的也许是我们写出的东东狗屁了,或者是速度变慢了。

大 多数的程序员知道Howto use exception 来处理我们的代码,可是很多人并不

是很重视异常的处理(国外的很多Code倒是处理的很好,Java的Exception机制

很不错)。异常处理机制是解 决某些问题的上佳办法,但同时它也引入了许多隐藏

的控制流程;有时候,要正确无误的使用它并不容易。

在 异常被throw后,没有一个方法能够做到使软件的行为具有可预测性和可靠性(这

句话不是我说的,是Jack Reeves写的Coping with Exception和Herb Sutter

写的Exception-Safe Generic Containers中的。)一个没有按照异常安全设计的

程序想Run 正常,是做梦,别去想没有异常出现的可能,

对 C程序来说,使用Error Code就可以了,为什么还要引入异常?因为异常不能被

忽略。如果一个函数通过设置一个状态变量或返回错误代码来表示一个异常状态,没

有办法保证函数调用 者将一定检测变量或测试错误代码。结果程序会从它遇到的异

常状态继续运行,异常没有被捕获,程序立即会终止执行。

在 C程序中,我们可以用int setjmp( jmp_buf env );和 void

longjmp( jmp_buf env, int value );这2个函数来完成和异常处理相识的功能,

但是MSDN中介绍了在C++中使用longjmp来调整stack时不能够对局部的对象

调用析构函数,但是 对C++程序来说,析构函数是重要的(我就一般都把对象的


本文标签: 没有 处理 使用