CPP学习备忘[13] 异常

来源:互联网 发布:虚拟货币交易软件 编辑:程序博客网 时间:2024/06/01 07:20
 

 

【1】异常使用三部曲

1.     框定异常(try语句块)

2.     定义异常处理(catch语句块)

3.     抛掷异常(throw语句)

前两个步骤是在一个函数中定义的,而抛掷异常则可以跨函数使用。当直接在try语句块中使用时,异常处理则退化为一般的错误处理模式;在try语句块中,会有一些语句调用了其他函数,它们之间则构成一个调用链,在调用链中的某一个节点上,如果出现抛掷语句,则便是一般意义上的异常了。

 

【2】异常机制捕捉的方式仍然是基于类型匹配。捕捉相当于函数返回类型的匹配,而不是函数参数的匹配,所以捕捉不用考虑抛掷中的多种数据类型匹配问题。

 

【3】异常机制是基于这样的原理:程序运行实质上是数据实体在做一些操作。因此发生异常现象的地方,一定是某个实体出现了差错,该实体所对应的数据类型便作为抛掷和捕捉的依据。因此,抛掷的实体已经存在,不需要通过类型转换来创建一个临时实体。实参与形参之间就理所当然地不能用相容类型提升这一规则来套。

    若捕捉不住则矛盾上交,即继续往函数的上层抛掷;若再没有捕捉到,则最后将以程序终止运行而告终。

 

【4】捕捉处理并不一定需要实参传递。有些情况下捕捉基于抛掷的类型匹配后,便着手处理异常了,而无须传递该类型的实体值。

 

【5】异常申述:

    void f() throw(A,B);  //f函数内可能会抛掷出A和B类型的异常;

    void g();  //g函数内可能会抛掷出任何类型的异常

    void h() throw();  //h函数内不会抛掷出任何异常

    如果h函数真的抛掷出异常,或者f函数抛掷出非A非B类型的异常,那么这是没有料到的,所以称其为未料到异常。

    异常申述是一种对设计的描述,从而给程序员一个编程的参照,所以应作为界面而放在函数声明中,并通过头文件的形式,扩散到程序员那里;

    其次,要使用异常申述,函数声明和函数定义中的异常申述必须保持一致,否则无法一一对应。

 

【6】terminate为系统默认的“强制捕捉器”,它的默认操作是调用系统的abort函数,从而无条件地终止程序的执行。

    未料到异常,如果不去理它,被系统截获后会转而去执行unexcepted函数,而该函数的默认行为也是执行terminate函数。一旦进入terminate函数,就无法再回头,因为它已经完全脱离了原先函数的栈结构,而进入非常有限的异常处理机构。到达terminate之后,一般就是准备终止运行。

    可以通过set_terminate函数修改捉不住异常的默认处理器,从而使得发生捕捉不住异常时,被自定义函数处理,如:

    void myTerminate(){…}

    set_Terminate(myTerminate);

    set_terminate函数在头文件exception中声明。原理与set_unexpected函数相似。

 

【7】异常设计一般是先根据程序中各种错误的分类和性质,定义一个异常的类继承体系。然后在进行了系统结构设计以后,进行异常捕捉方案设计。

    异常还可以设计为多态,这样处理起来就更能发挥类层次结构的优势了。

 

【8】通常在异常设计中,异常捕捉的类型采用异常的引用。引用传递的好处是,不需要为了传递抛掷的对象而创建一个异常对象,因为本身已经出错的程序,或许根本无能力创建对象。

    在主函数中使用系统异常exception的捕捉。一般来说,自定义了异常类层次结构,设计了其捕捉网,如果再有漏网的异常,那么,那些异常就是来自系统的了。

 

【9】构造函数没有返回类型,无法通过返回值来报告运行状态,所以只能通过一种非函数机制的途径,即异常机制,来解决构造函数的出错问题。

 

【10】通过动态转型一个基类引用到子类引用,不能通过测试引用值来断定引用的类型,因为引用值代表对象值转换的时刻,要么就运行出错,要么就初始化完成,代表了一个对象。因此,为了多态处理的完美性,系统应该支持引用动态转型失败的报告及处理,以让程序员能够对其失败进行编程。

    引用动态转型失败时,C++运行系统会自发地抛掷出一个标准异常exception的子类bad_cast异常。因此进行引用动态转型时,一般总是伴随着捕捉bad_cast的异常处理。

 

【11】typeid能够多态地抓取对象的类型信息。获取对象的类型信息,便可以进行所需的多态处理。这比直接操纵虚函数要灵活得多。

    typeid在typeinfo头文件中定义,typeid(objectName)为对象的类型,类型可以比较。typeid(objectName)。name为用C串表示的该类型的名称,可以用来打印类型信息。

 

原创粉丝点击