概述
做开发不仅仅要考虑到业务逻辑更要在写代码时将各种可能考虑周全,但是这又是很难的事情,毕竟开发就是个人的事,而使用者可能上万甚至百万级别。这时,程序的稳定性就极为重要,我们不能让程序因为某一处运行出问题而就直接导致程序或者产生其他更严重的后果,比如:做除法时当除数为零时,数组访问越界时,容器capacity不足而继续存储时等等,这些异常情况,如果不能发现并加以处理,很可能会导致程序崩溃。
异常处理的作用
运行时错误如果放任不管,系统就会执行默认的操作,终止程序运行,也就是我们常说的程序崩溃(Crash),如果我们能知道程序大概在什么地方出错,出错是什么类型的,那么开发者就能根据对应的错误类型做出相应的处理。下面通过一个简单的例子对比一下:
#include "stdafx.h"#include #include using namespace std ;int _tmain(int argc, _TCHAR* argv[]){string test = "i love u" ;char test_char = test.at(10) ;cout<
很明显test长度没有10,而test.at(10)显然会报错,并且at()是会在此时抛出异常的,但是我们并没有写异常处理代码,所以程序运行到test.at(10)就会崩溃从而自动退出。加上异常处理后看一下:
#include "stdafx.h"#include #include using namespace std ;int _tmain(int argc, _TCHAR* argv[]){string test = "i love u" ;try{char test_char = test.at(10) ;}catch(exception e){cout<
运行结果是:invalid string position
后面还有一大段重要业务代码
我们看到程序不仅没有崩溃中途退出并且输出了错误信息程序也继续往下继续执行。
上面只是C++异常处理的标准用法,下面讲一下异常处理需要注意的几个地方;
异常传递
我们都知道try{}catch{}代码块出现在方法体中,那么当方法存在多级调用时异常是怎么捕获的呢?我们通过几段代码来看一下:
首先这里申明并实现了两个方法funcA()和funcB();异常是在funcA()中抛出的,我们在funcB()中用了try{}catch{}块去捕获它。
void funcA(){throw "erro in funcA" ;}void funcB(){try{funcA() ;}catch(char* e){cout<
我们直接在main函数中不加异常处理代码直接调用funcB(),运行结果是:
catch in funcB:erro in funcA
然后我们在mian函数中调用funcB()时加上异常处理:
try{funcB();}catch(...){cout<
运行结果还是:catch in funcB:erro in funcA
这就说明,异常会被离抛出异常最近的try捕获
继续往下看:我们将funcB中的异常处理代码删除
void funcB(){funcA() ;}
此时如果在mian函数中直接调用funcB,毫无疑问程序会Crash掉,所以我们在调用funcB时加上try{}catch{}
try{funcB();}catch(char* e){cout<
运行结果为:catch in main:erro in funcA
get erro in funcB
后面还有一大段重要业务代码
以上说明:异常总是会被离抛出异常最近的try{}块捕获。如图:
多catch块匹配问题
假如,我们在捕获到异常后并不确定异常的类型,此时我们可能需要分开不同的类型来进行不同的处理,此时我们需要写多个catch块,此时我们就需要知道存在多个catch块时,异常的匹配顺序:
class A{};class B:public A{};void func(){throw B() ;}int _tmain(int argc, _TCHAR* argv[]){try{func();}catch(char* e){cout<
运行代码会发现此时输出的是A,说明异常捕获中也可以向上转型。
另外还有一个需要注意的点:catch(...),这个代码块代表捕获所有类型异常,这个不能写在最前面,不然的话会将后续的catch块全屏蔽,一般写在最后面做备用。
抛出自定义异常
异常必须显式地抛出,才能被检测和捕获到;如果没有显式的抛出,即使有异常也检测不到。日常中有很多系统定义的异常类型,也有很大方法系统有做异常检测,就比如上面举例讲到过的sting.at()方法是有做越界检查,并且其异常也是在exception类中。但是日常开发中很大时候需要我们自己定义异常类型,就比如除数为0这种情况,我们就以这个为例来看一下怎么定义自己的异常类型;
其实它的定义跟类的定义是一样的:
异常类实现:
class Zero{public:Zero();~Zero();void what() const{cout<
异常抛出代码实现:
double divide(){int a,b = 1 ;cin>>a>>b ;if (b == 0){throw Zero();}else{return a/b ;}}
捕获:
try{divide();}catch(Zero z){z.what();}
以上是最简单的例子,通过这个例子大家能弄明白异常从抛出到检测最后再到捕获的整个过程,大家在日常的开发中根据最简单的例子去丰富自己的业务代码就可以了。
谢谢大家!!手Key不易,点个关注再走呗~~~~
最后
以上就是丰富美女为你收集整理的pyqt5 捕获异常确保程序不退出_C++异常处理总结异常处理的作用异常传递多catch块匹配问题抛出自定义异常的全部内容,希望文章能够帮你解决pyqt5 捕获异常确保程序不退出_C++异常处理总结异常处理的作用异常传递多catch块匹配问题抛出自定义异常所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复