- 1、本文档共4页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C的错误和异常处理分析,c异常处理,c异常处理机制,c语言异常处理,c全局异常处理,c语言异常处理机制,linuxc异常处理,c异常处理框架,c中异常处理,objectivec异常处理
C++的错误和异常处理分析
何时使用异常?
一个简单的回答是:“当异常的语义和性能要求都恰当的时候。”
一个经常被提到的方法是这样问自己:“这是一个例外(或者意外的)情形吗?”
这个方法貌似挺吸引人,但是通常只会导致错误答案。对一个人来说是“异常”的情形对另
一个人却“正常”:当你真正仔细考虑这句话时,就发现无法作出区分,这句话根本帮不了
你。毕竟,如果你检查了某个错误条件,就意味着你认为它会发生,否则你的检查不过是垃
圾代码。
一个更合适的问法是:“这里需要栈展开吗?”由于异常处理实际上几乎都意味着
比正常流程代码要慢,还应该问自己:“这里负担得起栈展开的代价吗?”比如,正在做的
一个要花很长时间的计算,并且周期性地检测用户是否按下了取消键。抛出异常可以优雅地
取消操作。另一方面,在这个计算的内部循环中抛出并捕获处理异常可能就不恰当,这么做
可能导致严重的性能下降。前述内容包含这样一个原则:对于时间关键的代码,抛出异常才
是一种“异常”的做法,而不是常规.
如何设计异常类?
1. 从std::exception派生异常类。除了一些非常罕见的情况,例如负担不了需函
数的开销。把std::exception作为异常基类是合理的,当它被广泛使用后,将允许程序员
捕获任何异常而不必使用catch(...).更多关于catch(...)的内容,请看后文。
2. 使用虚拟继承。这个深刻的洞察力来自Andrew Koenig. 当抛出的一个异常是
从多个基类派生,并且这些基类有共同的部分,catch点就会遇到歧义问题,从异常基类虚
拟继承可以防止这种歧义问题:
#include iostream
strUCt my_exc1 : std::exception { char const* what() const throw(); };
struct my_exc2 : std::exception { char const* what() const throw(); };
struct your_exc3 : my_exc1, my_exc2 {};
int main()
{
try { throw your_exc3(); }
catch(std::exception const e) {}
catch(...) { std::cout whoops! std::endl; }
}
上面的程序将打印出“whoops”,因为C++运行时刻无法决定用那个exception实
例去匹配第一个catch.(秃子:我的建议是这里最好别使用多重继承)
3. 不要内嵌std::string对象或者其他拷贝构造可能抛出异常的数据成员、基类。
在上述点抛出异常将导致直接调用std::terminate().让基类或数据成员的默认构造函数
可能抛出异常也是同样糟糕的主意,你本来是打算通过一个包含对象构造的throw表达式报
告异常, 程序却无谓地中止了:
throw some_exception();
当发生异常拷贝时,有几种方法避免复制字符串对象,例如在异常对象中嵌入一个
定长存储区,或者通过引用计数来管理字符串。不过,在采用这些方法前,先考虑考虑下一
条。
4. 只在确实需要的时候才格式化what()返回的信息。格式化是一个典型的内存相
关的操作,有可能抛出异常。最好把格式化推迟到栈展开之后,因为栈展开可能释放某些资
源。对what()函数用catch(...)块加以保护是一个好主意,这样你就可以在格式化抛出异
常时有了一个退路。
5. 不要太在意what()的信息。在异常抛出点,对程序员来说,这是给出错误信息
的好机会,但是你未必能够把相关信息组合成用户可以理解的形式。国际化就一个典型的情
况。PeterDimov给出了良好建议:建一个错误信息格式化的表格,把what()的字符串作为
这个表的键。当标准库抛出异常时,如果我们只能获得其标准的what()字符串……
6. 在异常类的public接口中暴露导致错误的有关信息。返回固定信息的what()
意味着你忽视了暴露信息,而用户可能需要提供相关信息。例如,你的异常想报告数字范围
错,报错的代码应该能够透过异常的公共接口让异常包含导致问题的那个变量值。如果你只
是在
文档评论(0)