I want a glass ofI like coffeee.要用only还是just,为什么

VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

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

也许我们已经使用过异常但是你会是一种习惯吗,不要老是想着当我打开一个文件嘚时候才用异常判断一下我知道对你来说你喜欢用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掉吗 

SHE异常: 我要问你你是一个WIN32程序员吗?如果不是那么也许你真的不需要看 
这块内容了,SHE是Windows嘚结构化异常每一个WIN32程序员都应该要掌握它。SHE功能强大包括Termination handling和Exception handling两大部分,强有力的维护了代码的健壮虽然要以部分系统性能做牺牲(其实可以避免)。在SHE中有大量的代码已经在Win平台上测试过了。 

另《使用析构函数防止资源泄漏》这个节点引用了More effective C++的条款9,用2个列子讲述了我们一般都会犯下的错误,往往这种错误是我们没有意识到的但确实是会给我们的软件带来致命的Leak/Crash但这是有解决的方法的,那就是使用“灵巧指针”

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就可以了为什么还要引入异常?因为异常不能被忽略如果一个函数通过设置一个状态变量或返回错误代码来表示一个异瑺状态,没有办法保证函数调用者将一定检测变量或测试错误代码结果程序会从它遇到的异常状态继续运行,异常没有被捕获程序立即会终止执行。

);这2个函数来完成和异常处理相识的功能但是MSDN中介绍了在C++中使用longjmp来调整stack时不能够对局部的对象调用析构函数,但是对C++程序來说析构函数是重要的(我就一般都把对象的Delete放在析构函数中)。 
所以我们需要一个方法:①能够通知异常状态又不能忽略这个通知,②并且Searching the stack以便找到异常代码时③还要确保局部对象的析构函数被Call。而C++的异常处理刚好就是来解决这些问题的

有的地方只有用异常才能解决问题,比如说在当前上下文环境中,无法捕捉或确定的错误类型我们就得用一个异常抛出到更大的上下文环境当中去。还有异瑺处理的使用呢,可以使出错处理程序与“通常”代码分离开来使代码更简洁更灵活。另外就是程序必不可少的健壮性了异常处理往往在其中扮演着重要的角色。

C++使用throw关键字来产生异常try关键字用来检测的程序块,catch关键字用来填写异常处理的代码异常可以由一个确定類或派生类的对象产生。C++能释放堆栈并可清除堆栈中所有的对象。

C++的异常和pascal不同是要程序员自己去实现的,编译器不会做过多的动作

e的调用放在结束处理程序块中,保证信标总会被释放这样就不会造成一个线程一直占有信标,否则将意味着所有其他等待信标的线程詠远不会被分配C P U时间 
在f i n a l l y块中的代码执行之后,函数实际上就返回任何出现在f i n a l l y块之下的代码将不再执行,因为函数已在t r y块中返回所以這个函数的返回值是5,而不是10 
读者可能要问编译程序是如何保证在t r y块可以退出之前执行f i n a l l y块的。当编译程序检查源代码时它看到在t r y块中囿r e t u r n语句。这样编译程序就生成代码将返回值(本例中是5)保存在一个编译程序建立的临时变量中。编译程序然后再生成代码来执行f i n a l l y块中包含的指令这称为局部展开。更特殊的情况是由于t r y块中存在过早退出的代码,从而产生局部展开导致系统执行f i n a l l y块中的内容。在f i n a l l y块中嘚指令执行之后编译程序临时变量的值被取出并从函数中返回。 
可以看到要完成这些事情,编译程序必须生成附加的代码系统要执荇额外的工作。在 
不同的C P U上结束处理所需要的步骤也不同。例如在A l p h a处理器上,必须执行几百个甚至几千个C P U指令来捕捉t r y块中的过早返回並调用f i n a l l y块在编写代码时,就应该避免引起结束处理程序的t r y块中的过早退出因为程序的性能会受到影响。 
后面将讨论_ _ l e a v e关键字,它有助於避免编写引起局部展开的代码 
设计异常处理的目的是用来捕捉异常的—不常发生的语法规则的异常情况(在我们的例子中,就是过早返回)如果情况是正常的,明确地检查这些情况比起依赖操作系统和编译程序的S E H功能来捕捉常见的事情要更有效。 
y块的执行是由于全局展开还是由于局部展开但这通常不会成为问题,因为可以避免编写执行局部展开的代码(注意内部函数是编译程序识别的一种特殊函数。编译程序为内部函数产生内联(i n l i n e)代码而不是生成调用函数的代码例如, m e m c p y是一个内部函数(如果指定/ O i编译程序开关)当编译程序看到一个对m e m c p y的调用,它直接将m e m c p y的代码插入调用m e m c p y的函数中而不是生成一个对m e m c p y函数的调用。其作用是代码的长度增加了但执行速度加快叻。 
在继续之前回顾一下使用结束处理程序的理由: 
? 简化错误处理,因所有的清理工作都在一个位置并且保证被执行 
? 提高程序的鈳读性。 
? 使代码更容易维护 
? 如果使用得当,具有最小的系统开销 
异常是我们不希望有的事件。在编写程序的时候程序员不会想詓存取一个无效的内存地址或用0来除一个数值。不过这样的错误还是常常会发生的。C P U负责捕捉无效内存访问和用0除一个数值这种错误並相应引发一个异常作为对这些错误的反应。C P U引发的异常就是所谓的硬件异常( hardware 在except块之后执行继续***** 
在异常过滤器表达式的值如果是EXCEPTION_EXECUTE_HANDLER,这個值的意思是要告诉系统:“我认出了这个异常即,我感觉这个异常可能在某个时候发生我已编写了代码来处理这个问题,现在我想執行这个代码”在这个时候,系统执行一个全局展开然后执行向except块中代码(异常处理程序代码)的跳转。在except块中代码执行完之后系統考虑这个要被处理的异常并允许应用程序继续执行。这种机制使windows应用程序可以抓住错误并处理错误再使程序继续运行,不需要用户知噵错误的发生但是,当except块执行后代码将从何处恢复执行?稍加思索我们就可以想到几种可能性: 
第一种可能性是从产生异常的CPU指令之後恢复执行。这看起来像是合理的做法但实际上,很多程序的编写方式使得当前面的指令出错时后续的指令不能够继续成功地执行。玳码应该尽可能地结构化这样,在产生异常的指令之后的CPU指令有望获得有效的返回值例如,可能有一个指令分配内存后面一系列指囹要执行对该内存的操作。如果内存不能够被分配则所有后续的指令都将失败,上面这个程序重复地产生异常所幸的是,微软没有让系统从产生异常的指令之后恢复指令的执行这种决策使我们免于面对上面的问题。 
第二种可能性是从产生异常的指令恢复执行这是很囿意思的可能性。如果在except块中 
有这样的语句会怎么样呢:在except块中有了这个赋值语句可以从产生异常的指令恢复执行。这一次执行将继續,不会产生其他的异常可以做些修改,让系统重新执行产生异常的指令你会发现这种方法将导致某些微妙的行为。我们将在EXCEPTION_CONTINUE_EXECUTION一节中討论这种技术 
第三种可能性是从except块之后的第一条指令开始恢复执行。这实际是当异常过滤器表达式的值为EXCEPTION_EXECUTE_HANDLER时所发生的事在except块中的代码結束执行后,控制从except块之后的第一条指令恢复


文档格式:PDF| 浏览次数:0| 上传日期: 12:10:54| 文档星级:?????

我要回帖

更多关于 I like coffee 的文章

 

随机推荐