第十五章(2)

来源:互联网 发布:7.07 知乎 编辑:程序博客网 时间:2024/05/21 20:31

3. 异常

下面讲本章的重点类,异常。出了异常肯定要处理了,C++异常为处理异常提供了功能强大而灵活的工具。一个很简单的例子就是a/b,要是b是0怎么办

书中举了一个函数

double hmean(double a, double b) {return 2*a*b/(a+b); }

如果a=-b怎么办呢,最简单的方法就是调用abort方法终止程序

double hmean(double a, double b) 

{

if (a==-b)

abort();

return 2*a*b/(a+b); 

}

当然也可以将通过其他方式跳过这个函数或者终止程序,书中的例子说的很清楚了。

更高级的方法是使用异常机制来处理这个错误,简单的说就是使用try catch

例子15.9将hmean改写为

double hmean(double a, double b) 

{

if (a==-b)

throw "bad hmean() arguments: a = -b not allowed";

return 2*a*b/(a+b); 

}

然后主程序使用了一个try catch语句

先tryhmean这个函数,如果没问题则跳过catch程序块继续程序,如果a=-b,则hmean函数throw了一个字符串,主程序通过catch程序块catch了这个字符串,并运行catch内的程序,运行完之后才继续运行catch程序块之后的程序。这个理解起来应该没什么难度。


上面引发异常的函数throw的是一个字符串,通常引发异常的函数将传递一个对象,这样做的重要优点之一是可以使用不同的异常类型来区分不同的函数在不同情况下引发的异常。另外,对象可以携带信息,程序员可以根据这些信息来确定引发异常的原因。

书中就为hmean函数创建了一个这样的bad_hmean类,包含如果a=-b是的异常处理信息,这样hmean可以改成这样:

double hmean(double a, double b) 

{

if (a==-b)

throw bad_hmean(a,b);

return 2*a*b/(a+b); 

}

当然bad_hmean必须得给出相应的处理办法,书中的例子就是一个输出信息


假设try块没有直接调用引发异常的函数,而是调用了对引发一场函数进行调用的函数,则程序流将从引发异常的函数跳到包含try块和处理程序的函数。这个过程叫做栈解退

这其实是一个嵌套使用try catch的问题,当一个函数引发异常后,首先这个程序块终止,然后寻找最近一级的catch有没有catch到这个异常,如果没有,去上一级(调用这个函数的函数)中的catch看。书中的例子很好的解释了这一个过程。


虽然throw-catch机制类似于函数参数和函数返回机制,但还是有些不同之处。其中之一是函数fun()中的返回语句将控制权返回到调用fun()的函数,但throw语句将控制权向上返回到第一个这样的函数:包含能够捕获相应异常的try-catch组合。


有的时候一个异常类有继承次结构,这个时候要注意catch块的顺序:将捕获位于层次结构最下面的异常类的catch语句放在最前面,将捕获基类异常的catch语句放在最后面·。

还有的时候程序员也不知道被调用的函数可能引发哪些异常,在这种情况用...来代替异常,注意是三个点

catch { . . .} { statement}


异常,类和继承以三种方式相互关联:

可以从一个异常类派生出另一个

可以在类定义中嵌套异常类声明来组合异常

这种嵌套类本身可以被继承,还可用作基类

书中例子15.14给了一个很好的例子来解释他们之间的关系,其实跟这章前面讲的友元很像了。


其实异常处理实际用起来复杂很多了,如果程序员什么异常都考虑到到了,估计也不会有异常了,哈哈


4. RTTI运行阶段识别

dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针;否则该运算符将返回空指针

例如我们有个基类Grand,然后Superb继承Grand,Magnificent继承Grand

因为指向基类的指针可以指向派生类,我们可以声明三个指针

Grand * pg = new Grand;

Grand * ps = new Superb;

Grand * pm = new Magnificent;

我们可以这样声明一个指针

Superb * pm = dynamic_cast<Superb * > pg;

这样指针pg的类型是否可被安全的转换为Superb×,如果可以将返回对象的地址,否则返回一个空指针。

typeid和type_info一看名字就知道是来对类的类型进行操作的了,这里不细说了


0 0
原创粉丝点击