前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【答疑释惑】C++异常处理是咋回事?

【答疑释惑】C++异常处理是咋回事?

作者头像
程序员互动联盟
发布2018-03-16 11:08:49
8680
发布2018-03-16 11:08:49
举报
疑惑一

C++的异常处理

一、什么是异常处理

一句话:异常处理就是处理程序中的错误。

二、为什么需要异常处理,以及异常处理的基本思想

C++ 之父Bjarne Stroustrup在《The C++ Programming Language》中讲到:一个库的作者可以检测出发生了运行时错误,但一般不知道怎样去处理它们(因为和用户具体的应用有关);另一方面,库的用户知道 怎样处理这些错误,但却无法检查它们何时发生(如果能检测,就可以再用户的代码里处理了,不用留给库去发现)。

Bjarne Stroustrup说:提供异常的基本目的就是为了处理上面的问题。基本思想是:让一个函数在发现了自己无法处理的错误时抛出(throw)一个异常,然后它的(直接或者间接)调用者能够处理这个问题。

The fundamental idea is that a function that finds a problem it cannot cope with throws an exception, hoping that its (direct or indirect) caller can handle the problem.

也就是《C++ primer》中说的:将问题检测和问题处理相分离。

Exceptions let us separate problem detection from problem resolution

一 种思想:在所有支持异常处理的编程语言中(例如java),要认识到的一个思想:在异常处理过程中,由问题检测代码可以抛出一个对象给问题处理代码,通过 这个对象的类型和内容,实际上完成了两个部分的通信,通信的内容是“出现了什么错误”。当然,各种语言对异常的具体实现有着或多或少的区别,但是这个通信 的思想是不变的。

三、异常出现之前处理错误的方式

在C语言的世界中,对错误的处理总是围绕着两种方法:一是使用整型的返回值标识错误;二是使用errno宏(可以简单的理解为一个全局整型变量)去记录错误。当然C++中仍然是可以用这两种方法的。

这两种方法最大的缺陷就是会出现不一致问题。例如有些函数返回1表示成功,返回0表示出错;而有些函数返回0表示成功,返回非0表示出错。

还有一个缺点就是函数的返回值只有一个,你通过函数的返回值表示错误代码,那么函数就不能返回其他的值。当然,你也可以通过指针或者C++的引用来返回另外的值,但是这样可能会令你的程序略微晦涩难懂。

四、异常为什么好

在如果使用异常处理的优点有以下几点:

1. 函数的返回值可以忽略,但异常不可忽略。如果程序出现异常,但是没有被捕获,程序就会终止,这多少会促使程序员开发出来的程序更健壮一点。而如果使用C语 言的error宏或者函数返回值,调用者都有可能忘记检查,从而没有对错误进行处理,结果造成程序莫名其面的终止或出现错误的结果。

2. 整型返回值没有任何语义信息。而异常却包含语义信息,有时你从类名就能够体现出来。

3. 整型返回值缺乏相关的上下文信息。异常作为一个类,可以拥有自己的成员,这些成员就可以传递足够的信息。

4. 异常处理可以在调用跳级。这是一个代码编写时的问题:假设在有多个函数的调用栈中出现了某个错误,使用整型返回码要求你在每一级函数中都要进行处理。而使用异常处理的栈展开机制,只需要在一处进行处理就可以了,不需要每级函数都处理。

五、C++中使用异常时应注意的问题

任何事情都是两面性的,异常有好处就有坏处。如果你是C++程序员,并且希望在你的代码中使用异常,那么下面的问题是你要注意的。

1. 性能问题。这个一般不会成为瓶颈,但是如果你编写的是高性能或者实时性要求比较强的软件,就需要考虑了。(如果你像我一样,曾经是java程序员,那么下面的事情可能会让你一时迷糊,但是没办法,谁叫你现在学的是C++呢。)

2. 指针和动态分配导致的内存回收问题:在C++中,不会自动回收动态分配的内存,如果遇到异常就需要考虑是否正确的回收了内存。在java中,就基本不需要考虑这个,有垃圾回收机制真好!

3. 函数的异常抛出列表:java中是如果一个函数没有在异常抛出列表中显式指定要抛出的异常,就不允许抛出;可是在C++中是如果你没有在函数的异常抛出列表指定要抛出的异常,意味着你可以抛出任何异常。

4. C++中编译时不会检查函数的异常抛出列表。这意味着你在编写C++程序时,如果在函数中抛出了没有在异常抛出列表中声明的异常,编译时是不会报错的。而在java中,eclipse的提示功能真的好强大啊!

5. 在java中,抛出的异常都要是一个异常类;但是在C++中,你可以抛出任何类型,你甚至可以抛出一个整型。(当然,在C++中如果你catch中接收时使用的是对象,而不是引用的话,那么你抛出的对象必须要是能够复制的。这是语言的要求,不是异常处理的要求)。

6. 在C++中是没有finally关键字的。而java和python中都是有finally关键字的。

想了解更多C++异常知识,请关注公众号期待下一篇讲解。希望推荐优秀文章给我们,我们将分享给广大的编程爱好者,共同学习,共同成长。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员互动联盟 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档