版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1- 1-1 1知识回顾知识回顾i/oi/o流的概念流的概念输出流输出流输入流输入流2异常处理异常处理第八章第八章1- 1-3 3 理解异常处理的概念理解异常处理的概念 掌握异常处理的实现掌握异常处理的实现 掌握异常处理中对象的构造与析构掌握异常处理中对象的构造与析构 理解名字空间的概述理解名字空间的概述本章目标本章目标异常处理是异常处理是c+c+语言中重要的错误处理机制,语言中重要的错误处理机制,是提高程序容错性的一种手段。异常处理主要是提高程序容错性的一种手段。异常处理主要针对程序运行时出现的各种异常情况,提供发针对程序运行时出现的各种异常情况,提供发现,捕获异常的手段,并尽量减少异常对程
2、序现,捕获异常的手段,并尽量减少异常对程序运行的影响。运行的影响。有的程序虽然经过编译、连接成为可以运行的有的程序虽然经过编译、连接成为可以运行的程序,但在运行过程中难免会出现各种各样的问程序,但在运行过程中难免会出现各种各样的问题,即使对那些所谓能题,即使对那些所谓能“正常运行正常运行”的程序而言的程序而言也是如此。也是如此。程序中潜在的异常问题程序中潜在的异常问题提出问题提出问题示例:示例:#include #include using namespace std;int main()float a,b,c;double x1,x2;cout请输入一元二次方程的系数请输入一元二次方程的系数
3、a、b和和c的值的值:endl;couta;coutb;coutc;x1=(-b+sqrt(b*b-4*a*c)/(2*a);x2=(-b-sqrt(b*b-4*a*c)/(2*a);cout方程的实根是方程的实根是:x1=x1endl;cout方程的实根是方程的实根是:x2=x2endl;return 0;从上面例子可以看出:能够从上面例子可以看出:能够“正常运行正常运行”的程序可能的程序可能存在着许多潜在的存在着许多潜在的“隐患隐患”。程序运行可以检测到的。程序运行可以检测到的一些非正常情况称为异常(一些非正常情况称为异常(exception)。)。如除数为如除数为0、数组越界访问、内存空
4、间不够、输入、数组越界访问、内存空间不够、输入/输输出不正常(文件找不到、输入数据类型错等)等。出不正常(文件找不到、输入数据类型错等)等。异常是程序错误一种形式。异常是程序错误一种形式。分析问题分析问题程序中的错误按性质可分为语法错误、逻辑错程序中的错误按性质可分为语法错误、逻辑错误和异常误和异常3种。种。一般来说,异常的检测和处理要完成下列任务一般来说,异常的检测和处理要完成下列任务之一:之一:(1)让)让“用户用户”知道程序出现了异常,并退出知道程序出现了异常,并退出程序。程序。(2)让)让“用户用户”知道程序出现了异常,允许知道程序出现了异常,允许“用户用户”选择继续使用程序。选择继续
5、使用程序。(3)在程序发生异常时,能够在不打扰)在程序发生异常时,能够在不打扰“用户用户”的情况下继续程序的运行。的情况下继续程序的运行。c+c+语言异常处理机制的基本思想是将异常的检测与处理语言异常处理机制的基本思想是将异常的检测与处理分离。当在一个函数体中检测到异常条件存在,但无法确分离。当在一个函数体中检测到异常条件存在,但无法确定相应的处理方法时,将引发一个异常,并由函数直接或定相应的处理方法时,将引发一个异常,并由函数直接或间接调用检测并处理这个异常。间接调用检测并处理这个异常。这一基本思想用这一基本思想用3 3个保留字实现:个保留字实现:throwthrow、trytry和和cat
6、chcatch。在。在一般情况下,被调用函数直接检测到异常条件的存在并使一般情况下,被调用函数直接检测到异常条件的存在并使用用throwthrow引发一个异常(注意,引发一个异常(注意,c+c+语言的异常是由程序员语言的异常是由程序员控制引发的,而不是由计算机硬件或程序运行环境控制的控制引发的,而不是由计算机硬件或程序运行环境控制的);在上层调用函数中使用);在上层调用函数中使用trytry检测函数调用是否引发异检测函数调用是否引发异常,检测到的各种异常由常,检测到的各种异常由catchcatch捕获并作相应处理。捕获并作相应处理。异常处理实现异常处理实现在在vc+6.0环境中,为了使用异常处
7、理机制,需要进行环境中,为了使用异常处理机制,需要进行如下设置(默认设置):如下设置(默认设置):(1)选择菜单中的)选择菜单中的project。(2)在弹出的下拉菜单中选择)在弹出的下拉菜单中选择setting命令,出现命令,出现settings对话框。对话框。(3)打开)打开c/c+选项卡。选项卡。(4)在)在category中选择中选择 c+ language。(5)选中)选中enable exception handling复选框。复选框。在在c+程序中,任何需要检测异常的语句(程序中,任何需要检测异常的语句(包括函数调用)都必须在包括函数调用)都必须在try语句块中执行,语句块中执行
8、,异常必须由紧跟着异常必须由紧跟着try语句后面的语句后面的catch语句来语句来捕获并处理。因而,捕获并处理。因而,try与与catch总是结合使用总是结合使用。1、异常处理的语法、异常处理的语法throw、 try和和catch语句的一般语法如下:语句的一般语法如下:throw 表达式;表达式;try /try语句块语句块 catch(类型类型1 参数参数1) /针对类型针对类型1的异常处理的异常处理 catch(类型类型2 参数参数2) /针对类型针对类型1的异常处理的异常处理 .catch(类型(类型n 参数参数n) /针对类型针对类型1的异常处理的异常处理 异常处理的执行过程如下:异
9、常处理的执行过程如下:(1 1)控制通过正常的顺序执行到达)控制通过正常的顺序执行到达trytry语句,然后执行语句,然后执行trytry块内的块内的保护段。保护段。(2 2)如果在保护段执行期间没有引起异常,那么跟在)如果在保护段执行期间没有引起异常,那么跟在trytry块后的块后的catchcatch子句就不执行,程序从异常被抛掷的子句就不执行,程序从异常被抛掷的trytry块后跟随的最后一个块后跟随的最后一个catchcatch子句后面的语句继续执行下去。子句后面的语句继续执行下去。(3 3)如果在保护段执行期间或在保护段调用的任何函数中(直接)如果在保护段执行期间或在保护段调用的任何函
10、数中(直接或间接的调用)有异常被抛掷,则从通过或间接的调用)有异常被抛掷,则从通过throwthrow运算数创建的对象运算数创建的对象中创建一个异常对象(可能包含一个复制构造函数)。中创建一个异常对象(可能包含一个复制构造函数)。(4 4)如果匹配的处理器未找到,则运行函数)如果匹配的处理器未找到,则运行函数terminateterminate将被自动调将被自动调用,而函数用,而函数terminateterminate的默认功能是调用的默认功能是调用abortabort终止程序。终止程序。(5 5)如果找到了一个匹配的)如果找到了一个匹配的catchcatch处理程序,且它通过值进行捕获处理程
11、序,且它通过值进行捕获,则其形参通过复制异常对象进行初始化。,则其形参通过复制异常对象进行初始化。示例示例1:#include void main()char *buf;trybuf=new char512;if(buf=0)throw 内存分配错误内存分配错误!;cout内存分配成功内存分配成功!endl;catch(char *str)cout异常引发异常引发:strendl;示例示例2:#include int fun(int);void main()trycout4!=fun(4)endl;cout-2!=fun(-2)endl;cout5!=fun(5);catch (int n)c
12、outn=n不能计算不能计算n!endl;cout程序执行结束程序执行结束.endl;int fun(int n)if(n=0)throw n;int s=1;for(int i=1;i=n;i+)s*=i;return s;catch处理程序的出现次序很重要,因为在一个处理程序的出现次序很重要,因为在一个try块中,异常处理块中,异常处理程序是按照它出现的次序检查的。只要找到一个匹配的异常类型,程序是按照它出现的次序检查的。只要找到一个匹配的异常类型,后面的异常处理都将被忽略。后面的异常处理都将被忽略。示例示例3:#include void fun(int code)tryif(code=0
13、) throw code; /引发引发int类型的异常类型的异常if(code=1) throw x; /引发引发char类型的异常类型的异常if(code=2) throw 12.345; /引发引发double类型的类型的异常异常catch(int n)cout捕获整数类型:捕获整数类型:nendl;catch(char c)cout捕获字符类型:捕获字符类型:cendl;catch(double d)cout捕获双精度类型:捕获双精度类型:dendl;return;void main()fun(0);fun(1);fun(2);程序中同时列出多个程序中同时列出多个catch语句时,将以语
14、句时,将以catch语句在程序中出现语句在程序中出现的次序作类型匹配,并且只有一个匹配的的次序作类型匹配,并且只有一个匹配的catch语句被执行,其语句被执行,其他的他的catch语句将被忽略。语句将被忽略。catch(.)是一个特殊的捕获语句,可以捕获任何异常,因而在是一个特殊的捕获语句,可以捕获任何异常,因而在任何情况下其他任何情况下其他catch子句都不被检查。所以,子句都不被检查。所以,catch(.)应该放应该放在最后。在在最后。在vc+6.0中,若中,若catch(.)不是放在所有不是放在所有catch(.)语句的最后,则会出现编译错误。语句的最后,则会出现编译错误。2、捕获异常、
15、捕获异常示例示例1:#include void fun(int code)tryif(code=0) throw code; /引发引发int类型的异常类型的异常 if(code=1) throw x; /引发引发char类型的异常类型的异常 if(code=2) throw 12.345; /引发引发double类型的异常类型的异常catch(int n) cout捕获整数类型捕获整数类型.nendl;catch(.) cout默认捕获默认捕获.endl;return;void main()fun(0);fun(1);fun(2);从前面异常处理的例子可以看出,调用一个函数时,除从前面异常处
16、理的例子可以看出,调用一个函数时,除了了解函数的参数与返回值外,还必须了解函数的异常了了解函数的参数与返回值外,还必须了解函数的异常引发方式,以便设计异常处理程序,应付函数调用过程引发方式,以便设计异常处理程序,应付函数调用过程中引发的异常。中引发的异常。异常的引发与捕获已成为函数之间界面的一部分,有必异常的引发与捕获已成为函数之间界面的一部分,有必要在函数原型中也列出异常引发。要在函数原型中也列出异常引发。例如:例如:void fun(int i) throw(t1,t2,t3);3、带有异常声明的函数原型、带有异常声明的函数原型c+的异常处理机制不仅能够处理各种不同类型的异常,的异常处理机
17、制不仅能够处理各种不同类型的异常,还具有为抛出异常前构造所有局部对象自动调用析构函数还具有为抛出异常前构造所有局部对象自动调用析构函数的能力。的能力。在程序中,找到一个匹配的在程序中,找到一个匹配的catch异常处理后,如果异常处理后,如果catch子句的异常类型说明是一个值参数,则其初始化方式是复子句的异常类型说明是一个值参数,则其初始化方式是复制被抛出的异常对象。如果制被抛出的异常对象。如果catch子句的异常类型说明是子句的异常类型说明是一个引用,则其初始化方式是使该引用指向异常对象。一个引用,则其初始化方式是使该引用指向异常对象。当当catch子句的异常类型说明参数被初始化后,便于始展
18、子句的异常类型说明参数被初始化后,便于始展开栈的过程。这包括将从对应的开栈的过程。这包括将从对应的try块开始到异常被抛出之块开始到异常被抛出之间构造(且尚未析构)的所有自动对象进行析构。析构的间构造(且尚未析构)的所有自动对象进行析构。析构的次序与构造的次序相反。然后程序从最后一个次序与构造的次序相反。然后程序从最后一个catch处理处理之后开始恢复执行。之后开始恢复执行。异常处理中对象的构造与析构异常处理中对象的构造与析构示例:示例:#include void fun(void);class apublic:a() ;a() ;const char *showreason() const
19、/异常处理成员函数异常处理成员函数return 异常在异常在a类中类中;class bpublic:b();b();b:b()coutb构造函数构造函数endl;b:b()coutb析构函数析构函数endl; void fun()b b;coutfun():抛掷一个抛掷一个a异常异常endl;throw a();void main()cout进入进入main()endl;trycout在在try块中调用块中调用fun()endl;fun();catch( a e)cout在在catch处理器捕获一个异常类型:处理器捕获一个异常类型:;coute.showreason()endl;catch(c
20、har *str)cout捕获其他异常:捕获其他异常:strendl;cout返回返回main()endl;在名字空间中可以放入这样的声明:类、变量(以及它在名字空间中可以放入这样的声明:类、变量(以及它们的初始化)、函数(以及它们的定义)、模板以及其们的初始化)、函数(以及它们的定义)、模板以及其他名字空间。从而这些变量或函数都与该名字空间相关他名字空间。从而这些变量或函数都与该名字空间相关联。联。名字空间概述名字空间概述1、名字空间的定义、名字空间的定义保留字(保留字(namespace)用于定义名字空间。名字空间必)用于定义名字空间。名字空间必须在程序的全局作用域内定义,不能在函数内或类
21、内部须在程序的全局作用域内定义,不能在函数内或类内部定义,最外层名字空间的名字必须在程序的全局作用域定义,最外层名字空间的名字必须在程序的全局作用域惟一。惟一。名字空间可以分多次定义,即可以先在初始定义中定义名字空间可以分多次定义,即可以先在初始定义中定义一部分成员,然后在扩展定义中再定义另一部分成员,一部分成员,然后在扩展定义中再定义另一部分成员,或者再定义初始时声明函数原型。初始定义和扩展定义或者再定义初始时声明函数原型。初始定义和扩展定义的语法格式相同。的语法格式相同。保留字保留字using用于声明程序要引入的名字空间成员,或用于声明程序要引入的名字空间成员,或都用于指示程序要引用的名字
22、空间。在声明引用名字空都用于指示程序要引用的名字空间。在声明引用名字空间的某个成员之前,成员必须已经在名字空间中进行了间的某个成员之前,成员必须已经在名字空间中进行了声明或进行了定义。声明或进行了定义。示例示例#include namespace ns1 /初始定义名字空间初始定义名字空间ns1extern int x; /说明整型变量说明整型变量xvoid fun(int); /说明函数说明函数fun(int)void fun(long) /定义函数定义函数fun(long)coutprocessing a long argument endl;namespace ns1 /扩展定义名字空间
23、扩展定义名字空间ns1int x=5; /定义整形变量定义整形变量xvoid fun(int) /定义函数定义函数fun(int)coutprocessing a int argumentendl;void main()int y=20;using ns1:x; /说明引用变量说明引用变量xusing:ns1:fun; /说明引用函数说明引用函数fun()x=10;fun(4);fun(4l);coutx=xendl;couty=yendl;1、访问名字空间的成员、访问名字空间的成员访问名字空间的成员有访问名字空间的成员有4种方式:种方式:(1)直接访问成员)直接访问成员格式如下:格式如下:名
24、字空间名字名字空间名字:成员名字成员名字因此,直接访问总能惟一地访问指定名字空间的成员。因此,直接访问总能惟一地访问指定名字空间的成员。(2)指定名字空间(使用)指定名字空间(使用using namespace 语句)语句)指定名字空间的格式如下:指定名字空间的格式如下:using namespace 名字空间;名字空间;/直接使用成员名字直接使用成员名字(3)声明引用成员(使用)声明引用成员(使用using语句)语句)声明引用成员的格式如下:声明引用成员的格式如下:using 名字空间名字空间:名字名字/直接使用成员名字直接使用成员名字(4)使用别名法)使用别名法声明引用成员的格式如下:声明
25、引用成员的格式如下:namespace 别名别名=名字空间;名字空间;/使用使用“别名别名:成员名字成员名字”本方法与直接方法成员方法类似,只是加了一个别名。例如有以下两本方法与直接方法成员方法类似,只是加了一个别名。例如有以下两个名字空间个名字空间nsa和和nsb,分别声明了同名的类模板:,分别声明了同名的类模板:namespace nsa template class array private: t *ia; int ssize; ;以上的类以上的类array被封装在名字空间被封装在名字空间nsa中,在使该类前,中,在使该类前,必须使必须使nsa名字空间可见。名字空间可见。namespa
26、ce nsb template class array private: t *ia; int ssize; ;以上的类以上的类array被封装在名字空间被封装在名字空间nsb中,在使该类前,必须使中,在使该类前,必须使nsb名字空间可见。因为使用了名字空间,两个名字空间可见。因为使用了名字空间,两个array类分别在不同的名类分别在不同的名字空间中,所以不会存在冲突。其中四种使用方式如下:字空间中,所以不会存在冲突。其中四种使用方式如下:第一种用法:直接用法。第一种用法:直接用法。nsa:array a;nsb:array b;第二种用法:指定名字空间。第二种用法:指定名字空间。using
27、namespace nsa;array a;using namespace nsb;array b;第三种用法:声明引用成员。第三种用法:声明引用成员。using nsa:array;array a;using nsb:array; /错误,存在同名的成员错误,存在同名的成员array b;值得注意的是,上述语句是错误的,应将两个类模板改为不同的名字值得注意的是,上述语句是错误的,应将两个类模板改为不同的名字,如将,如将nsb中的中的array改为改为array1,则以下语句是正确的:则以下语句是正确的:using nsa:array;array a;using nsb:array1;arra
28、y b;第四种用法:使用别名法。第四种用法:使用别名法。namespace us=nsa;namespace ms=nsb;us:array a;ms:array b;示例:示例:#include namespace ns1int x=10; namespace ns2int x=20; void main()using ns1:x;coutx=xendl;using ns2:x;coutx=xendl;2、使用作用域运算符、使用作用域运算符“:”访问成员访问成员当名字空间的成员和程序的全局标识符同名时,可以通当名字空间的成员和程序的全局标识符同名时,可以通过作用域运算符过作用域运算符“:”既
29、定程序的全局标识符;当名字空既定程序的全局标识符;当名字空间的成员和程序的标识符同名时,首先访问的是程序的间的成员和程序的标识符同名时,首先访问的是程序的局部标识符。局部标识符。示例:示例:#include int x=20; /全局变量全局变量namespace ns1int x=10;void main()using namespace ns1;coutx=:xendl;3、名字空间的嵌套、名字空间的嵌套名字空间也可以像类那样嵌套,形成多个层次的作用域名字空间也可以像类那样嵌套,形成多个层次的作用域,因此,在访问名字空间的成员时,就有可能使用多个,因此,在访问名字空间的成员时,就有可能使用
30、多个域运算符。域运算符。示例:示例:#include namespace ns1 /ns1的初始定义的初始定义int x=10;void fun1()coutns1s fun1()endl;namespace ns2int y=20;void fun2()coutns2s fun2()endl;using ns1:fun1; /using说明,全局名字空间限定说明,全局名字空间限定fun1using ns1:x; /using说明,全局名字空间限定说明,全局名字空间限定xusing ns1:ns2:fun2; /using说明,多重名字空间限定说明,多重名字空间限定fun2using ns1:
31、ns2:y; /using说明,多重名字空间限定说明,多重名字空间限定yvoid main()fun1();fun2();coutx=xendl;couty=yendl;4、 std名字空间名字空间本章前面的程序都是使用标准本章前面的程序都是使用标准c+编写的,其头文件都编写的,其头文件都带有带有.h扩展名,而扩展名,而ansi/iso标准标准c+头文件不带扩展头文件不带扩展名。这是因为名。这是因为c+是从是从c发展而来,某些头文件,如发展而来,某些头文件,如math.h都是从都是从c中沿袭过来的,而诸如中沿袭过来的,而诸如iostream.h、iostreamip.h和和fstream.h等是特别为等是特别为c+设计的。当设计的。当一个头文件被包含进某一个程序中,头文件中的全局标一个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度码头环境监测与污染风险防控服务协议4篇
- 美容院2025年度美容师服务质量监控合同范本4篇
- 二零二五版智能交通系统检测与维护合同3篇
- 2025年度PVC光伏组件生产合作协议3篇
- 2025年度宠物活体销售合同模板(含宠物培训课程包)3篇
- 2025年度池塘水域渔业资源养护与增殖合同范本4篇
- 2025年厂房物业管理与可持续发展战略协议4篇
- 二零二五年度新型房产交易代理合同4篇
- 二零二五年度航空航天制造劳务合作合同3篇
- 2025年度产学研合作促进科技成果转化合同4篇
- 带状疱疹护理查房课件整理
- 年月江西省南昌市某综合楼工程造价指标及
- 奥氏体型不锈钢-敏化处理
- 作物栽培学课件棉花
- 交通信号控制系统检验批质量验收记录表
- 弱电施工验收表模板
- 绝对成交课件
- 探究基坑PC工法组合钢管桩关键施工技术
- 国名、语言、人民、首都英文-及各地区国家英文名
- API SPEC 5DP-2020钻杆规范
- 组合式塔吊基础施工专项方案(117页)
评论
0/150
提交评论