C++大学基础教程课件_第1页
C++大学基础教程课件_第2页
C++大学基础教程课件_第3页
C++大学基础教程课件_第4页
C++大学基础教程课件_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C++第13章异常处理程序设计的要求之一就是程序的健壮性。希望程序在运行时能够不出或者少出问题。但是,在程序的实际运行时,总会有一些因素会导致程序不能正常运行。异常处理(ExceptionHandling)就是要提出或者是研究一种机制,能够较好的处理程序不能正常运行的问题。2023/2/73/45为什么强调异常处理电信系统的特点要求稳定,全年运行时间>99.999%用户数量巨大,使用频繁例:BBS系统程序:稳定>功能2023/2/75/4513.1.1异常及其特点异常(Exceptions)是程序在运行时可能出现的会导致程序运行终止的错误。编译系统检查出来的语法错误,程序的逻辑错误,都不属于异常。异常是一个可以正确运行的程序在运行中可能发生的错误。常见的异常,如:系统资源不足。如内存不足;磁盘空间不足等。用户操作错误导致运算关系不正确。如出现分母为0,数组越界等。2023/2/76/4513.1.2异常处理方法及举例对于程序中的异常,通常有三种处理的方法:不作处理。发布相应的错误信息,然后,终止程序的运行。适当的处理异常,一般应该使程序可以继续运行。而在C++中,异常处理(ExceptionHandling)就是用try-throw-catch的模式进行异常处理的机制。2023/2/77/45例13.1程序将连续地输入两个实数,通过调用函数,返回这两个数相除的商。并且要注意除数不能为0。#include<iostream.h>#include<stdlib.h>doubledivide(doublea,doubleb){ if(b==0) //检测分母是不是为0 {

cout<<"除数不可以等于0!"<<endl; abort(); //调用abort函数终止运行 }

returna/b;}voidmain(){…调用divide…}用一般的方法处理程序异常第十三章异常处理13.1异常和异常处理13.2C++异常处理机制13.3用类的对象传递异常13.4异常处理中的退栈和对象析构2023/2/710/4513.2C++异常处理机制try{受保护语句;

throw

异常; 其他语句;}catch(异常类型){异常处理语句;}检测和抛掷异常扑获和处理异常try模块2023/2/711/45voidf(){……

throw

异常 ……}main(){ try { f(); 其他语句; } catch(异常类型) {异常处理语句;}}2023/2/713/45例13.2用C++的异常处理机制,重新处理例13.1。#include<iostream>#include<stdlib.h>using

namespacestd;doubledivide(doublea,doubleb){

if(b==0) {

throw"输入错误:除数不可以等于0!"; }

returna/b;}2023/2/714/45void

main(){doublex,y,z;

cout<<"输入两个实数x和y:";

while(cin>>x>>y){ try { z=divide(x,y); }

catch(const

char*s) //startofexceptionhandler {

cout<<s<<"\n";

cout<<"输入一对新的实数:";

continue; } //endofhandler

cout<<"x除以y等于"<<z<<"\n";

cout<<"输入下一组数<q表示结束>:";}

cout<<"程序结束,再见!\n";}2023/2/715/4513.2C++异常处理机制程序运行的一种结果是: 输入两个实数x和y:1.23.2 x除以y等于0.375 输入下一组数<q表示结束>:3.40 输入错误:除数不可以等于0! 输入一对新的实数:2.34.5 x除以y等于0.511111 输入下一组数<q表示结束>:q 程序结束,再见!2023/2/717/4513.2C++异常处理机制例13.2的执行过程可以简要的表示如下:第十三章异常处理13.1异常和异常处理13.2C++异常处理机制13.3用类的对象传递异常13.4异常处理中的退栈和对象析构2023/2/719/4513.3用类的对象传递异常throw语句所传递的异常,可以是各种类型的:整型、实型、字符型、指针,等等。也可以用类对象来传递异常。优势在于可以传递和处理异常有关的行为或者方法。专门用来传递异常的类称为异常类。异常类可以是用户自定义的,也可以是系统提供的exception类。2023/2/721/452.43.21push(10.8)2.4push(2.4)2.43.21push(3.21)10.8push(1.2)pop()pop()pop()10.82.43.21pop()2023/2/722/4513.3.1用户自定义类的对象传递异常现在,我们用C++异常处理的机制,改写这个程序。可以定义两个异常类:“栈空异常”类在try块中,如果检测到“栈空异常”,就throw一个“StackEmptyException”类的对象“栈满异常”类。如果检测到“栈满异常”,就throw一个“StackOverflowException”类的对象。2023/2/723/45//例13.3:带有异常处理的栈#include<iostream>usingnamespacestd;classStackOverflowException //栈满异常类{public: StackOverflowException(){} ~StackOverflowException(){}

voidgetMessage(){cout<<"异常:栈满不能入栈。"<<endl;}};classStackEmptyException //栈空异常类{public: StackEmptyException(){} ~StackEmptyException(){}

voidgetMessage(){cout<<"异常:栈空不能出栈。"<<endl;}};2023/2/725/45template<class

T,inti> //push成员函数定义voidMyStack<T,i>::push(constTitem){if(top>0)StackBuffer[--top]=item;elsethrowStackOverflowException(); //抛掷对象异常

return;}2023/2/726/45

template<classT,inti> //pop成员函数定义TMyStack<T,i>::pop(void){if(top<i)returnStackBuffer[top++];elsethrowStackEmptyException(); //抛掷另一个对象异常}2023/2/729/4513.3.1用户自定义类的对象传递异常通过异常类对象的引用,直接调用异常类的成员函数getMessage,来处理异常。在try语句块后面直接有两个catch语句来捕获异常。也就是说,要处理的异常增加时,catch语句的数目也要增加。运行结果表明,10次循环都已经完成。没有出现因为空栈时不能出栈而退出运行的情况。2023/2/730/4513.3.2用exception类对象传递异常C++提供了一个专门用于传递异常的类:exception类。可以通过exception类的对象来传递异常。classexception{public:exception(); //默认构造函数

exception(char*); //字符串作参数的构造函数

exception(constexception&);exception&operator=(constexception&);virtual~exception(); //虚析构函数

virtualchar*what()const; //what()虚函数private:char*m_what;};2023/2/731/4513.3.2用exception类对象传递异常其中和传递异常最直接有关的函数有两个:带参数的构造函数。参数是字符串,一般就是检测到异常后要显示的异常信息。what()函数。返回值就是构造exception类对象时所输入的字符串。可以直接用插入运算符“<<”在显示器上显示。2023/2/732/4513.3.2用exception类对象传递异常如果捕获到exception类对象后,只要显示关于异常的信息,则可以直接使用exception类。如果除了错误信息外,还需要显示其他信息,或者作其他的操作,则可以定义一个exception类的派生类,在派生类中可以定义虚函数what的重载函数,以便增加新的信息的显示。2023/2/733/4513.3.2用exception类对象传递异常例13.4定义一个简单的数组类。在数组类中重载“[]”运算符,目的是对于数组元素的下标进行检测。如果发现数组元素下标越界,就抛掷一个对象来传递异常。并且要求处理异常时可以显示越界的下标值。2023/2/734/4513.3.2用exception类对象传递异常我们使用exception类的对象来传递对象。但是,直接使用exception类对象还是不能满足例题的要求。因为不能传递越界的下标值。为此,可以定义一个exception类的派生类ArrayOverflow。其中包含一个数据成员k。在构造ArrayOverflow类对象时,用越界的下标值初始化这个数据k。在catch块中捕获到这个对象后,可以设法显示对象的k值。2023/2/735/45

//例13.4用exception类参与处理异常#include<iostream>#include<exception>usingnamespacestd;classArrayOverflow:publicexception //exception类的派生类{public:ArrayOverflow::ArrayOverflow(inti):exception("数组越界异常!\n"){k=i;} constchar*what() //重新定义的what()函数 {cout<<"数组下标"<<k<<"越界\n"; returnexception::what(); }private:intk;}; //派生类ArrayOverfow定义结束2023/2/736/45

classMyArray //数组类的定义{int*p; //数组首地址

intsz; //数组大小

public:MyArray(ints){p=newint[s];sz=s;} //构造函数~MyArray(){delete[]p;}intsize(){returnsz;}int&operator[](inti); //重载[]运算符的原型};int&MyArray::operator[](inti) //重载[]运算符{if(i>=0&&i<sz)returnp[i];throwArrayOverflow(i);}2023/2/737/45

voidf(MyArray&v);voidmain(){MyArrayA(10);f(A);}voidf(MyArray&v){//……for(inti=0;i<3;i++){try{if(i!=1){v[i]=i;cout<<v[i]<<endl;} elsev[v.size()+10]=10; }catch(ArrayOverflow&r){cout<<r.what();}} //for循环结束}程序运行后输出:0数组下标20越界数组越界异常!213.4异常处理中的退栈 和对象析构

2023/2/7北京邮电大学电信工程学院计算机技术中心39/4513.4异常处理中的退栈和对象析构在函数调用时,函数中定义的自动变量将在堆栈中存放。结束函数调用时,这些自动变量就会从堆栈中弹出,不再占用堆栈的空间,这个过程有时被称为“退栈”(Stackunwinding)。其他的结束动作还包括调用析构函数,释放函数中定义的对象。2023/2/7北京邮电大学电信工程学院计算机技术中心40/4513.4异常处理中的退栈和对象析构但是,如果函数执行时出现异常,并且只是采用简单的显示异常信息,然后退出(exit)程序的做法,则程序的执行就会突然中断,结束函数调用时必须完成的退栈和对象释放的操作也不会进行。这样的结果是很不希望的。2023/2/741/45

floatfunction3(intk) //function3中可能有异常{if(k==0){cout<<"function3中发生异常\n"; //显示异常信息

exit(1);} //退出执行

elsereturn123/k;}voidfunction2(intn) {ForTestA12;function3(n); //第三次调用}voidfunction1(intm){ForTestA11;function2(m); //第二次调用}voidmain(){function1(0); //第一次调用} 2023/2/7北京邮电大学电信工程学院计算机技术中心42/4513.4异常处理中的退栈和对象析构程序运行后显示:

function3中发生异常在function1和fuction2中分别定义了ForTest类的对象。如果函数可以正常退出,这些对象将被释放。但是,程序运行后只显示了异常信息。没有析构函数被调用的迹象。说明所创建的对象没有被释放。如果采用C++的异常处理机制来进行处理。情况就会完全不同。2023/2/7北京邮电大学电信工程学院计算机技术中心43/4513.4异常处理中的退栈和对象析构如果在function3中用throw语句来抛掷异常,就会开始function3的退栈。然后,返回到函数function2开始function2的退栈,,并且调用ForTest类析构函数,释放对象A12。接着,返回到函数function1开始function1的退栈,,并且调用ForTest类析构函数,释放对象A11。2023/2/744/45

例13.6用C++异常处理机制来重新编写例13.5。//例13.6:用C++异常处理机制,对象可以完全释放//Demonstratingstackunwinding.#include<iostream>#include<stdlib.h>#include<exception>using

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论