资源描述
Edit Master title,Click to edit Master text styles,Second level,Third level,第9章异常处理,*,*,面向对象程序设计,八、异常处理,10/27/2026,1,第9章异常处理,内容提要,程序中潜在的异常问题,异常处理机制,C+中的异常处理,标准异常,使用异常处理应注意的几个问题,10/27/2026,2,第9章异常处理,提出问题,【例】求解一元二次方程ax2+bx+c=0,#include,#include,using namespace std;,int main(),float a,b,c;,double x1,x2;,coutabc;,x1=(-b+sqrt(,b*b-4*a*c,)/2*a;,x2=(-b-sqrt(,b*b-4*a*c,)/2*a;,cout方程的实根是:x1=x1 x2=x2endl;,return 0;,10/27/2026,3,第9章异常处理,异常处理机制,需要进行异常处理,从而减少异常对程序运行的影响,提高程序的容错性。,异常处理机制提供了系统层次上的标准设施,其主要任务有以下几点:,能够在异常发生时,在执出点抛出异常,并将有关异常的信息以类型的形式传递到异常处理模块;,建立模块之间的异常通信机制,特别是在多层模块之间实现异常有序的传递,保证抛出的每个异常都能被适当的异常处理模块捕获。,保证异常发生时能自动释放异常模块所占用的系统资源。,对于不执行异常处理的代码没有任何额外的运行负担。,将异常处理代码从普通代码中分离出来。,10/27/2026,5,第9章异常处理,C+中的异常处理,异常的抛出、检测和捕获,异常在多层模块间的传递,异常接口声明,异常处理中析构函数的调用,异常类的层次结构,10/27/2026,6,第9章异常处理,异常的抛出、检测和捕获,异常抛出、检测和捕获的语法定义如下:,异常抛出:,throw 表达式;,异常的检测和捕获由try-catch结构实现:,try,被检测可能会发生异常的语句,catch(,异常的类型,),异常处理的语句,10/27/2026,7,第9章异常处理,int main(),float a,b,c;,double x1,x2;,coutabc;,try,if(0=a),throw a,;/b并无意义,代表float型即可,if(b*b-4*a*c)0),throw 1.0,;,x1=(-b+sqrt(b*b-4*a*c)/2*b;,x2=(-b-sqrt(b*b-4*a*c)/2*b;,cout方程的实根是:x1=x1 x2=x2endl;,catch(float),/捕获float类型的异常,cout系数b不能为0,方程无解!endl;,catch(double),/捕获double类型的异常,cout开方为负值,方程无解!endl;,cout程序结束!endl;,return 0;,10/27/2026,8,第9章异常处理,fun1(int a,int b,int c)/捕获异常并重新抛出异常,try,return(-b+fun2(a,b,c)/(2*a);,catch(ZERO),throw,;/重新抛出异常,int main(),float a,b,c;,coutabc;,try,cout方程的一个实根是:x1=fun1(a,b,c)endl;,catch(ZERO S1)/捕获除数为零异常,并处理异常,coutS1.s,方程无解!endl;,catch(NEGATIVE S2)/捕获开方值为负数异常,并处理异常,coutS2.s,方程无解!endl;,cout程序结束!endl;,return 0;,10/27/2026,10,第9章异常处理,异常接口声明,在使用可能抛出异常的函数时,可能需要知道该函数抛出的异常类型,C+专门提供了异常接口声明,也称为异常规范。,其语法形式如下:,函数类型 函数名(函数参数表),throw(异常类型表),其中异常类型表包括该函数中所有可以抛出的异常类型,异常类型之间用逗号分开。,异常接口声明是函数接口的一部分,是函数使用者和函数之间的协议。,10/27/2026,12,第9章异常处理,void Fun(),intArray ia(10);,cout 在Fun()中抛掷整型异常。endl;,throw 1;,int main(),try,cout 在主函数的try块中调用函数Fun()。endl;,Fun();,catch(int),cout 在主函数catch子句捕获到整型异常,;,cout 并进行异常处理。endl;,cout 程序结束!endl;,return 0;,10/27/2026,14,第9章异常处理,异常类的层次结构,#include,#include,using namespace std;,class Excp /声明异常基类,public:,static void print(string msg)/打印错误信息,coutmsgendl;,;,class pushOnFull:public Excp /声明栈满异常类,public:,pushOnFull(int i):tempvalue(i),int getTempValue()return tempvalue;,private:,int tempvalue;/存放异常发生时没有压栈的值,;,10/27/2026,15,第9章异常处理,class popOnEmpty:public Excp ;/声明栈空异常类,class newError:public Excp ;/声明动态分配内存异常类,class otherError:public Excp ;/声明其它异常类,class Stack,public:,Stack(int capacity=10)throw(newError);/建立一空栈,Stack()delete elements;/析构函数,释放数组资源,void push(int value)throw(pushOnFull);/压栈,void pop(int/出栈,bool isfull()return top maxsize?false:true;,bool isempty()return top?false:true;,int size()return top;,void display();,private:,int top;/栈顶指针,int*elements;/存放栈中元素的栈数组,int maxsize;/栈可容纳元素的个数,;,10/27/2026,16,第9章异常处理,Stack:Stack(int capacity):top(0),maxsize(capacity),elements=new intcapacity;/动态创建栈数组,if(0=elements)throw newError();/如果分配失败抛出异常,void Stack:pop(int&top_value),if(isempty()throw popOnEmpty();/栈空,则抛出异常,top_value=elements-top;,void Stack:push(int value),if(isfull(),throw pushOnFull(value);/栈满抛出异常,elementstop+=value;,void Stack:display(),if(!size(),cout 栈中已没有元素!n;return;,cout (栈中有 size()个元素)(bottom:;,for(int i=0;i top;+i),cout elementsi ;,cout :top)n;,10/27/2026,17,第9章异常处理,int main(),int i,n,count;,try,cout n;,Stack myStack(n);,cout n;,for(i=1;i=n;count=+i),myStack.push(i);,myStack.display();,cout n;,for(i=1;i=n;count=i+),int x;,myStack.pop(x);,cout 已出栈count个元素!n;,10/27/2026,18,第9章异常处理,标准异常,C+标准库提供的标准异常类的层次结构,exception,logic_error,runtime_error,bad_alloc,bad_exception,bad_cast,bad_typeid,ios_base:failure,length_error,domain_error,out_of_range,invalid:argument,range_error,overflow_error,underflow:error,10/27/2026,20,第9章异常处理,标准异常,标准异常的根是exception类,其声明如下:,namespace std /exception 类在命名空间std 中,class exception,public:,exception()throw();/缺省构造函数,exception(const exception/拷贝构造函数,exception/析构函数,/what()返回一个字符串,用于异常的文本描述。,virtual const char*what()const throw();,;,10/27/2026,21,第9章异常处理,char&operator(int i)const,if(i=size),string es=数组越界!;,throw out_of_range(es);,/将es字符串传入对象,return cai;,private:,int size;,char*ca;,;,10/27/2026,23,第9章异常处理,int main(),try,char ca=A,B,C,D,E,F;,Array CA(ca,sizeof(ca)/sizeof(char);,CA5=X;/正常访问字符数组类,CA6=G;/越界访问数组类将引发异常,return 0;,catch(,const out_of_range&excp,),cout excp.what()endl;/获取异常信息,return-1;,10/27/2026,24,第9章异常处理,使用异常处理应注意的几个问题,使用标准异常和异常接口声明,在创建自定义的异常类型前,应检查标准C+异常库。如果标准异常正合所需,就拿来为我所用,这样会使我们的程序更易于理解和使用。如果标准异常不能满足要求,则尽量从某个标准异常中派生新增加的异常类型。,异常接口声明像一个函数原型:它完整列举了函数可能抛出的所有异常。异常接口声明是函数及其调用者间契约的一部分。换句话说,函数承诺不抛出其它任何不在异常接口声明中的异常。在函数设计时声明异常接口,即便于用户了解函数的异常类型,又能给编译器提供该函数的抛出异常的种类,让编译器“监督”函数是否按照其声明抛出异常。,10/27/2026,26,第9章异常处理,使用异常处理应注意的几个问题,不要将异常处理当成程序控制结构来使用,异常的抛出和捕获有点像函数的调用与返回,而try-catch结构看上去像switch语句。如果在程序中把异常处理当成程序控制流程的手段,可能会带来程序的混乱和执行的低效率。,尽量避免在构造和析构函数中抛出异常,10/27/2026,27,第9章异常处理,本章小结,程序中潜在的异常问题,异常处理机制,C+中的异常处理,标准异常,使用异常处理应注意的几个问题,10/27/2026,28,第9章异常处理,
展开阅读全文