当前位置: 首页 > news >正文

遵义营商环境建设局网站wordpress 图片域名

遵义营商环境建设局网站,wordpress 图片域名,百度热议,怎样学好网站开发计算机应用程序中离不开错误处理#xff0c;尤其是生产型大型软件系统。应用软件系统运行属于循环处理事务#xff0c;出错后需要保证不能让软件程序直接退出。这就需要使用一定的程序容错处理来应对。一般情况下#xff0c;大型软件开发中的软件系统容错处理会结合异常处理… 计算机应用程序中离不开错误处理尤其是生产型大型软件系统。应用软件系统运行属于循环处理事务出错后需要保证不能让软件程序直接退出。这就需要使用一定的程序容错处理来应对。一般情况下大型软件开发中的软件系统容错处理会结合异常处理、错误代码定义的使用与相应的出错处理日志记录包括一定的参与大型生产系统的监控系统等配合保障系统的稳定性。下面本章将会就C软件系统中提供的异常处理作详细的讲述包括基本概念以及应用操作情况。 14.1  C异常处理简介 软件应用程序中异常处理机制是一种比较有效的处理系统运行时错误的方法。C针对异常处理提供了一种标准的方法用于处理软件程序运行时的错误并用于处理软件系统中可预知或不可预知的问题。这样就可以保证软件系统运行的稳定性与健壮性。 C中异常的处理主要用于针对程序在运行时刻出现错误而提供的语言层面的保护机制。它允许开发者最大限度地发挥针对异常处理进行相应的修改调整。 C应用程序中在考虑异常设计时并不是所有的程序模块处理都需要附加上异常情况的处理。相对来说异常处理没有普通方法函数调用速度快。过度的错误处理会影响应用程序运行的效率。通常在C开发的软件系统中应用程序都由对应的库、组件以及运行的具体不同模块组成。在设计时异常的处理应充分考虑到独立程序库以及组件之间的情况。便于使用者在程序出现异常情况下使用库或者组件的开发者能够快速定位出库、组件还是应用程序的错误。 由于大型软件系统中库与组件通常都是以独立的程序方式提供给具体设计开发模块人员。开发人员通常不了解组件与库中具体实现情况只是根据提供的接口来操作使用。在不清楚具体库与组件的具体实现情况下开发者可能在极端的情况下操作应用库或者组件提供的方法。此时相应的异常处理通信就会成为必不可少的错误处理通信机制。下面将会就C语言提供的异常机制支持作详细应用讲述在实践中总结异常应用的场合与具体实现方法。 14.2  C异常处理方法 C语言异常部分的支持也是在后续语言发展中逐步讨论并添加的内容。该语言针对异常处理提供了一系列的语法支持。C语言除了提供异常的关键字语法支持以外其标准库中支持异常处理而封装异常类也很好的为应用程序中异常处理判断使用提供直接的帮助。 14.2.1  C异常处理try、throw与catch C语言中针对异常处理提供了三个关键字分别为try、throw与catch。C应用程序中通过这三个关键字实现机制组合来实现异常的处理。下面通过常见异常处理操作方式来介绍应用程序中使用异常处理关键字的基本方式其基本语法定义如下所示。 try { …               //可能出错产生异常的代码 throwtypen(); } catch(type1) { …               //对应类型的异常处理代码 } catch(type2) { …               //对应类型的异常处理代码 } …                        //更多类型异常处理代码 或者 try { function();//调用可能会抛出异常的函数方法 } catch(type1) { …               //对应类型的异常处理代码 } catch(type2) { …               //对应类型的异常处理代码 } … C应用程序中try关键字后的代码块中通常放入可能出现异常的代码。随后的catch块则可以是一个或者多个catch块主要用于异常对应类型的处理。try块中代码出现异常可能会对应多种异常处理情况catch关键字后的圆括号中则包含着对应类型的参数。 try块中代码体作为应用程序遵循正常流程执行。一旦该代码体中出现异常操作会根据操作的判断抛出对应的异常类型。随后逐步的遍历catch代码块此步骤与switch控制结构有点相像。当遍历到对应类型catch块时代码会跳转到对应的异常处理中执行。如果try块中代码没有抛出异常则程序继续执行下去。 try体中可以直接抛出异常或者在try体中调用的函数体中间接的抛出。下面将会通过一个简单的异常处理实例来使用C语言中支持的异常处理方式。 1.准备实例 打开UE工具创建新的空文件并且另存为chapter1401.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端客户端通过scrt工具访问操作。程序代码文件编辑如下所示。 /** * 实例chapter1401 * 源文件chapter1401.cpp * 简单异常处理 */ #include iostream #include string using namespace std; int main() { try { intvalue1,value2;                                                                       //定义两个整型变量 coutPleaseinput two value:endl;                                //提示输入信息 cinvalue1value2;                                                              //从键盘输入两个整型数 coutMaybeexception code:endl;                                //提示可能出现异常的代码信息 if(value2 0)                                                                            //如果除数为0则抛出异常 { throw 0; } else                                                                                               //否则直接计算相除操作 { coutvalue1/value2:(value1/value2)endl; } } catch(inti)                                                                                            //捕捉参数为整型的异常 { coutdivisoris 0!endl;                                                      //异常处理代码 } return0; } 本实例程序主要通过try…catch方式来捕获异常演示简单容错处理的一般实现方法。程序主要在main()函数内部定义实现具体程序剖析见程序注释与后面讲解。 2.编辑makefile Linux平台下需要编译源文件为chapter1401.cpp相关makefile工程文件编译命令编辑如下所示。 OBJECTSchapter1401.o CCg chapter1401: $(OBJECTS) $(CC)$(OBJECTS) -g -o chapter1401 clean: rm-f chapter1401 core $(OBJECTS) submit: cp-f -r chapter1401 ../bin cp-f -r *.h ../include 上述makefile文件套用前面的模板格式主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入表明程序编译同时加入了可调式信息。 3.编译运行程序 当前shell下执行make命令生成可执行程序文件。随后通过make submit命令提交程序文件至本实例bin目录。通过cd命令定位至实例bin目录执行该程序文件运行结果如下所示。 [developerlocalhost src]$ make g    -c-o chapter1401.o chapter1401.cpp g chapter1401.o -g -o chapter1401 [developer localhost src]$ make submit cp -f -r chapter1401 ../bin cp -f -r *.h ../include [developer localhost src]$ cd ../bin [developer localhost bin]$ ./chapter1401 Please input two value: 12 0 Maybe exception code: divisor is 0! 本实例中主要演示了除法中除数为0时抛出相应的异常并作出对应的处理。本实例中try块中主要放置着可能出现异常的代码。该代码块中首先定义两个整型变量value1与value2。随后提示从键盘输入两个整型数接着输出可能出现异常的提示信息。最后判断输入的除数value2是否为0。如果该判断条件成立即程序执行中发生了除数为0的错误则对应的代码体中使用throw抛出异常。如果判断条件不成立则程序继续执行下去 一旦符合抛出异常条件成立则执行相应代码采用throw关键字抛出异常。此时关键字后跟着一个整型数0表示该异常。随后catch语句块捕捉异常由于catch随后的参数类型符合抛出异常的类型匹配则执行catch中的异常处理即打印输出除数为0的提示信息。在主程序中try块中抛出的异常的类型需要与随后的catch中参数类型一致否则会程序将会异常终止。初学者可以将上述catch中参数类型修改为double类型测试看看当前编译器针对异常发生后匹配不到对应的catch时给出的反应。 如果try块中的代码没有抛出异常则程序会直接忽略随后的catch块直接执行后续的代码处理。在设计程序可能出现的异常处理时将抛出异常的类型与对应的catch块中的类型规范的对应起来有助于程序在异常处理加入后更加清晰有条理。 14.2.2  throw抛出异常处理 C程序中异常抛出是采用关键字throw实现的。通常throw关键字后会跟随着一个操作数该操作数可以是一个表达式、一个C内置类型数据或者为类类型的对象等。最常见的异常抛出都会放在try代码块中。当然C也允许抛出异常的地方在函数中供try块中的代码调用。正常情况下异常抛出点的定义不要放在try块外部无关的地方因为那样通常会引起编译器默认的终止程序处理。最好的情况下异常抛出点直接或者间接的定义在try块中。 try块中可以包含一个或者多个异常抛出点。但是需要注意的是异常只要一抛出对应的catch块捕捉到后该try块中以下的代码体执行会被终止。代码执行直接进入对应的catch块中最后catch块执行处理完异常后直接跳转至所有当前try块对应的catch块之后。 下面通过一个具体的实例来演示throw异常抛出的基本操作与需要注意的使用情况。 1.准备实例 打开UE工具创建新的空文件并且另存为chapter1402.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端客户端通过scrt工具访问操作。程序代码文件编辑如下所示。 /** * 实例chapter1402 * 源文件chapter1402.cpp * 简单异常处理 */ #include iostream #include string using namespace std; void divideCompute(int value1,int value2)                                              //除法计算函数定义 { if(value1 0)                                                                            //如果被除数为0则抛出参数类型为浮点型异常 { throw0.0; } elseif(value2 0)                                                                    //如果除数为0则抛出参数类型为整型异常 { throw0; } else                                                                                               //否则执行除法运算并打印输出结果 { coutvalue1/value2:(value1/value2)endl; } } int main() { try { intvalue1,value2;                                                    //定义两个整型变量 coutPleaseinput two value:endl;             //提示输入两个整型数信息 cinvalue1value2;                                            //输入两个整型数 coutMaybeexception code:endl; divideCompute(value1,value2);                                    //调用除法计算函数传入两个输入的整型参数 } catch(inti)                                                                         //捕捉整型参数异常 { coutdivisoris 0!endl;                                   //对应的异常处理 } catch(doublei)                                                                          //捕捉浮点型参数异常 { coutdividendis 0!endl;                               //对应的异常处理 } couthere!endl;                                                       //异常处理块后的正常代码 return 0; } 本实例通过throw关键字演示在函数内部抛出异常程序调用处捕获异常并处理的场景。程序主要由函数divideCompute与主函数main组成具体程序剖析见程序注释与后面讲解。 2.编辑makefile Linux平台下需要编译源文件为chapter1402.cpp相关makefile工程文件编译命令编辑如下所示。 OBJECTSchapter1402.o CCg chapter1402: $(OBJECTS) $(CC)$(OBJECTS) -g -o chapter1402 clean: rm-f chapter1402 core $(OBJECTS) submit: cp-f -r chapter1402 ../bin cp-f -r *.h ../include 上述makefile文件套用前面的模板格式主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入表明程序编译同时加入了可调式信息。 3.编译运行程序 当前shell下执行make命令生成可执行程序文件。随后通过make submit命令提交程序文件至本实例bin目录。通过cd命令定位至实例bin目录执行该程序文件运行结果如下所示。 [developerlocalhost src]$ make g    -c-o chapter1402.o chapter1402.cpp g chapter1402.o -g -o chapter1402 [developer localhost src]$ make submit cp -f -r chapter1402 ../bin cp -f -r *.h ../include [developer localhost src]$ cd ../bin [developer localhost bin]$ ./chapter1402 Please input two value: 0 0 Maybe exception code: dividend is 0! here! 本实例中主要设计了除法中可能出现的异常。此处抛出异常没有直接放在try代码块中而是通过间接的方式放置在函数定义中供try代码块中调用。此时除法操作定义的函数中包含着可能出现的两个异常抛出点。一类是针对被除数为0时抛出浮点型参数异常。另一类则针对除数为0时抛出整型参数异常。 整个主程序代码中catch主要有两个参数类型的捕获处理。分别对应着除数以及被除数为0时异常抛出捕获处理。上述实例表明try代码块中可以直接放置或者间接放置多个throw异常抛出点。一旦其中一个异常点抛出后程序控制权将会转移到对应的catch参数类型异常处理中。对应的异常处理完后将会意味着程序执行将会终止try异常块中的程序块。直接转移到对应的所有catch异常处理块之后的代码执行。 上述主程序中从try块中开始执行try代码快中首先定义两个整型变量value1与value2。随后提示从键盘输入两个整型数上述程序执行后输入两个整型数都为0。之后将输入的两个整型数作为除法计算函数的实参调用除法计算函数。根据传入的实参首先判断被除数为0则抛出浮点型参数异常随后程序转移到对应catch块中执行异常处理输出提示信息“dividend is 0!”。程序代码转移至catch处理块中之后则退出了异常抛出的所在块。直接处理完毕后转到所有catch块之后继续执行代码即最后执行输出“here!”提示信息代码。 14.2.3  catch捕捉异常处理 catch关键字的代码块则主要负责异常的捕获处理catch块可以拥有多个并且紧跟着try块之后。 每个catch块部分主要由圆括号中参数类型紧跟其后的大括号中异常代码处理部分构成。前面小节在讲述异常抛出处理时已经对其使用的原理作过解释即当在可能抛出异常的try代码块中通过throw抛出了异常。随后开始匹配catch块中的“参数类型”是否符合异常抛出时的类型如果符合则执行对应catch块中的代码处理。 多个catch块中遍历到对应的catch块则执行随后代码块处理异常。catch块中随后圆括号中参数类型该类型可以拥有变量名称或者对象名称也可以直接是对应的参数类型。如果是对应的类型对象则在catch块中可以引用该对象处理。而如果是只有数据类型没有相应参数名称的参数则直接匹配对应的参数类型即可程序会从try块中转移至catch块中执行。 如果异常抛出了匹配对应的catch块没有对应类型的异常处理时则会调用默认的异常abort来终止程序的执行。 catch块中的参数除了采用基本的内置类型、自定义类类型外还可以使用三个点的省略号即catch(…)来表示捕捉所有的异常。 此时当try块中一旦抛出异常时如果对应的catch块中只有一个catch(…)或者对应的catch(…)放置在所有其它catch块最后。那么异常发生时只会执行对应的catch(…)中的代码处理或者当前面所有的catch都匹配不到时则匹配catch(…)捕获所有异常处理。【前面的catch匹配不到则匹配catch(...)类似switch中的case1、case2、...default】通常情况下捕捉所有异常的定义会放在所有其它catch块最后位置这样的好处就是程序不会因为抛出异常匹配不到对应的catch块而终止。 上述实例代码作出如下修改根据实例中添加catch(…)块观察捕捉异常处理情况。 1.准备实例 打开UE工具创建新的空文件并且另存为chapter1403.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端客户端通过scrt工具访问操作。程序代码文件编辑如下所示。 /** * 实例chapter1403 * 源文件chapter1403.cpp * 捕获所有异常处理 */ #include iostream #include string using namespace std; void divideCompute(int value1,int value2)                                              //除法计算函数定义 { if(value2 0)                                                                            //如果除数为0则抛出相应的整型异常 { throw0; } else                                                                                               //否则计算除法运算并打印结果 { coutvalue1/value2:(value1/value2)endl; } } int main() { try { intvalue1,value2;                                                             //定义两个整型变量 coutPleaseinput two value:endl; cinvalue1value2;                                                     //从键盘输入两个整型值 coutMaybeexception code:endl; divideCompute(value1,value2);                                             //调用除法计算函数 } catch(doublei)                                                                                   //对应浮点型参数异常处理 { coutdoubleexception!endl; } catch(inti)                                                                                  //对应整型参数异常处理 { coutdivisoris i”!”endl; } catch(...)                                                                                      //捕获所有异常处理  【前面的catch没有捕获到则在这里捕获】 { coutallexception!endl; } couthere!endl; return0; } 本实例主要通过catch(…)方式使用演示在异常处理相关类型捕获不到的情况下异常的默认处理情况。程序主要由函数divideCompute()与主函数main()组成程序具体剖析见程序注释与后面程序讲解。 2.编辑makefile Linux平台下需要编译源文件为chapter1403.cpp相关makefile工程文件编译命令编辑如下所示。 OBJECTSchapter1403.o CCg chapter1403: $(OBJECTS) $(CC)$(OBJECTS) -g -o chapter1403 clean: rm-f chapter1403 core $(OBJECTS) submit: cp-f -r chapter1403 ../bin cp-f -r *.h ../include 上述makefile文件套用前面的模板格式主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入表明程序编译同时加入了可调式信息。 3.编译运行程序 当前shell下执行make命令生成可执行程序文件随后通过make submit命令提交程序文件至本实例bin目录通过cd命令定位至实例bin目录执行该程序文件运行结果如下所示。 [developerlocalhost src]$ make g    -c-o chapter1403.o chapter1403.cpp g chapter1403.o -g -o chapter1403 [developer localhost src]$ make submit cp -f -r chapter1403 ../bin cp -f -r *.h ../include [developer localhost src]$ cd ../bin [developer localhost bin]$ ./chapter1403 Please input two value: 1 0 Maybe exception code: divisor is 0! here! 上述实例中主程序中根据输入的实参整型数调用除法计算函数。在除法计算函数中一旦除数为0则抛出整型参数为0的异常。此时开始匹配try块对应后的catch块中的参数类型。首先对比第一个catch块由于其参数类型为double类型不符合类型匹配则继续向下搜索。try块后的第二个捕捉异常处理catch块中的参数类型为整型并且该参数还拥有参数类型对应变量。匹配到该catch块后程序转移到对应的代码块中处理该代码块中主要用于打印输出说明除数为0此时则直接引用了参数类型后的变量名。 主程序中上述匹配到的catch块执行完之后直接转移至所有catch块之后继续执行。执行最后打印输出语句。此时如果前面几个catch都没有匹配对应的参数类型时则catch(…)块中异常处理代码会被执行初学者可以自行修改程序进行测试学习。 14.2.4  throw重抛异常处理 重新抛出异常通常应用在try嵌套层中。最常见的应用即当前try块中捕捉异常块不作任何处理时可以通过重抛异常让try层外部的catch块来处理。如果try层外部已经没有对应的try与catch块处理则会调用默认的异常处理终止程序。【异常处理嵌套时逐层抛出处理】 下面将会通过一个完整实例来演示异常重抛的应用情况。 1.准备实例 打开UE工具创建新的空文件并且另存为chapter1404.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端客户端通过scrt工具访问操作。程序代码文件编辑如下所示。 /** * 实例chapter1404 * 源文件chapter1404.cpp * throw重抛异常处理 */ #include iostream #include string using namespace std; void divideCompute(int value1,int value2) { try { if(value2 0)                                                //如果除数为0则抛出异常 { throw 0;                                                   //抛出整型异常 } else                                                                   //否则计算除法运算 { coutvalue1/value2:(value1/value2)endl; } } catch(doublei)                                                                 //捕捉浮点型参数异常 { coutdoubleexception!endl; }catch(inti)                                                                //捕捉整型参数异常 { coutrethrowexception:endl; throw;                                                                //重抛异常 }catch(...)                                                                   //捕捉所有类型异常 { coutallexception!endl; } } int main() { try { intvalue1,value2;                                           //定义两个整型变量 coutPleaseinput two value:endl; cinvalue1value2;                                  //输入两个整型变量 coutMaybeexception code:endl; divideCompute(value1,value2);                           //调用除法计算函数 } catch(doublei)                                                                 //外层捕捉浮点型异常 { coutdoubleexception!endl; }catch(inti)                                                                //外层捕捉整型异常 { coutdivisoris i!endl; }catch(...)                                                                   //外层捕捉所有类型异常 { coutallexception!endl; } couthere!endl; return0; } 本实例程序主要演示try…catch嵌套使用中通过throw关键字重新抛出异常的功能。程序主要由函数divideCompute与主函数组成程序具体剖析见程序注释与后面讲解。 2.编辑makefile Linux平台下需要编译源文件为chapter1404.cpp相关makefile工程文件编译命令编辑如下所示。 OBJECTSchapter1404.o CCg chapter1404: $(OBJECTS) $(CC)$(OBJECTS) -g -o chapter1404 clean: rm-f chapter1404 core $(OBJECTS) submit: cp-f -r chapter1404 ../bin cp-f -r *.h ../include 上述makefile文件套用前面的模板格式主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入表明程序编译同时加入了可调式信息。 3.编译运行程序 当前shell下执行make命令生成可执行程序文件。随后通过make submit命令提交程序文件至本实例bin目录。通过cd命令定位至实例bin目录执行该程序文件运行结果如下所示。 [developerlocalhost src]$ make g -c -o chapter1404.o chapter1404.cpp g chapter1404.o -g -o chapter1404 [developerlocalhost src]$ make submit cp -f -r chapter1404 ../bin cp -f -r *.h ../include [developerlocalhost src]$ cd ../bin [developerlocalhost bin]$ ./chapter1404 Please input two value: 1 0 Maybe exception code: rethrow exception: divisor is 0! here! 本实例中主要演示了try块中调用除法计算方法。该方法中又存在try与catch块的嵌套处理情况。上述实例主程序中同样是定义两个整型变量value1与value2随后从键盘输入两个整型数作为实参调用除法计算函数。除法计算函数中仍然包含着try块try块中包含着可能抛出异常的代码。一旦输入的实参中除数为0则报出整型类型的异常被随后的catch整型参数块所捕获执行相对应的异常处理代码。 在对应的异常处理catch块中允许针对异常不作出任何的处理而直接使用throw不带任何的参数类型重新抛出异常交由外层的catch块来捕获。此时代码执行被转移至外层catch块进行匹配。如果匹配到整型类型的异常处理时则进入执行相应的异常处理。如果没有匹配到则执行catch(…)块捕获所有异常随后转移至catch块外继续执行。 上述实例程序执行时传入两个整型数1和0。由于除数为0则在除法函数体中try块抛出异常。此时最内一层catch开始进行捕获匹配匹配到整型参数类型异常处理则进入执行。最内层的catch整型参数中除了打印输出提示重抛异常信息外则执行throw重抛异常。被外层对应的catch块捕获进入执行相应异常处理通过直接引用捕获异常参数类型的变量打印除数为0的信息提示。 14.3  C类体系中异常处理 C中异常机制同样可以应用于自定义类类型。在C程序中大部分的异常处理都是应用于自定义类类型。通常情况下定义处理异常的类然后再创建一个专门用于描述对应异常错误的对象实例。最后在应用程序中利用这个异常类对象实例处理应用的代码中可能发生的异常错误。 14.3.1  类类型中异常基本应用 类体系中异常的处理情况其实与函数中大致相仿。但由于自定义类型加入了封装、继承等特性其异常处理变得稍微复杂。通常情况下大型的软件系统中往往会自定义异常类供其它模块程序包含使用。下面将讲解一个自定义异常类以及在类中使用该异常类的实例读者可以了解异常在类体系中的应用情况与需要注意的问题。 1.准备实例 打开UE工具创建新的空文件并且另存为chapter1405_01.h、chapter1405_02.h与chapter1405_01.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端客户端通过scrt工具访问操作。程序代码文件编辑如下所示。 /** * 实例chapter1405 * 源文件chapter1405_01.h chapter1405_02.h chapter1405_02.cpp * 异常类的封装 */ #ifndef EXCEPTION_H_ #define EXCEPTION_H_ #include iostream #include string using namespace std; //自定义异常类 class MyException { public: //异常类无参数默认构造函数定义 MyException()                                                 { m_context ;                                      //初始化异常信息数据成员为空 } //异常类空析构函数定义 ~MyException(){} //异常类字符串类型参数构造函数定义 MyException(const string right) { m_context right;                                 //初始化异常信息数据为字符串对象参数 } //异常类字符串指针类型参数构造函数定义 MyException(const char * right) { m_context right;                                 //初始化异常信息数据为字符串指针参数 } //异常类返回异常信息接口方法定义 stringwhat() const { return m_context;                                  //直接返回相应的异常信息数据成员 } private: string   m_context;                                       //字符串类型数据成员表示异常信息 }; #endif //异常测试类除法计算类头文件chapter1405_02.h #include chapter1405_01.h //自定义除法计算类 class Compute { public: Compute(intvalue1,int value2);                           //除法计算类构造函数两个整型参数列表 ~Compute(){}                                                  //除法计算类空析构函数定义 void divideCompute();                                  //除法计算类除法计算方法成员 private: intm_value1;                                                  //除法计算类数据成员表示被除数 intm_value2;                                                  //除法计算类数据成员表示除数 }; //异常测试类除法计算类源文件chapter1405_02.cpp #include chapter1405_02.h Compute::Compute(int value1,int value2)                            //除法计算类构造函数定义 { m_value1 value1;                                                //初始化被除数数据成员 m_value2 value2;                                                //初始化除数数据成员 } void Compute::divideCompute()                                   //除法类除法计算方法成员定义 { try { if(m_value2 0)                                          //如果除数为0则抛出相应异常 { throwMyException(divisor is 0!); } else                                                                            //否则计算两数相除并打印结果 { coutm_value1/m_value2:(m_value1/m_value2)endl; } } catch(MyException e)                                         //捕获对应异常类型 { string errorMessage e.what();                            //定义错误信息字符串对象获取对应异常信息 couterrorMessageendl;                       //打印输出对应的异常信息 } catch(...)                                                                   //捕获所有异常 { string errorMessage Don’t knowerror!;//捕获所有异常处理信息 couterrorMessageendl; } } int main() { intvalue1,value2;                                                    //定义两个整型变量 coutPleaseinput two value:endl;             //提述输入两个整型数据 cinvalue1value2;                                          //从键盘输入两个整型数 Computecompute(value1,value2);                     //定义计算类对象同时传入输入的两个整型数构造初始化 compute.divideCompute();                                   //计算类对象调用其除法计算方法 return0; } 本实例通过封装异常处理类类型演示异常处理在C应用程序中的使用方法。程序主要由异常类、程序计算类以及主函数组成具体剖析见程序注释与后面讲解。 2.编辑makefile Linux平台下需要编译源文件为chapter1405_02.cpp相关makefile工程文件编译命令编辑如下所示。 OBJECTSchapter1405_02.o CCg chapter1405_02: $(OBJECTS) $(CC)$(OBJECTS) -g -o chapter1405_02 clean: rm-f chapter1405_02 core $(OBJECTS) submit: cp-f -r chapter1405_02 ../bin cp-f -r *.h ../include 上述makefile文件套用前面的模板格式主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入表明程序编译同时加入了可调式信息。 3.编译运行程序 当前shell下执行make命令生成可执行程序文件随后通过make submit命令提交程序文件至本实例bin目录通过cd命令定位至实例bin目录执行该程序文件运行结果如下所示。 [developerlocalhost src]$ make g    -c-o chapter1405_02.o chapter1405_02.cpp g chapter1405_02.o -g -o chapter1405_02 [developerlocalhost src]$ make submit cp -f -r chapter1405_02 ../bin cp -f -r *.h ../include [developerlocalhostsrc]$ cd ../bin [developerlocalhostbin]$ ./chapter1405_02 Please input two value: 12 0 divisor is 0! 上述实例中主要演示了异常机制在C面向对象类类型中的应用情况。功能与前面除数为0的实例相仿。本实例中首先定义异常类MyException。该类主要用于用于异常抛出和捕捉时的对象类型。异常类中主要包含成员四个不同类型的构函数、一个获取异常信息的what方法成员、一个私有保护型的数据成员用于表示异常信息内容。 MyException类中3个构造函数第一个为无参数默认构造定义将异常信息内容初始化为空。第二个则参数为string型的对象构造使用字符串初始化数据成员。第三个则参数为字符串指针的对象构造使用字符串指针初始化异常数据成员。异常类中的方法成员what中主要返回异常信息用于在应用程序中捕获并打印输出。 计算类主要用于两数除法运算。该类中主要包含一个构造函数、一个空析构函数以及一个计算两个数除法的方法。另外它包含两个整型的数据成员分别表示除法中的两个数。该类的构造函数中主要通过传入的两个整型参数初始化对应的数据成员计算除法的方法实现与前面的除法计算实例相同仅仅是抛出的异常类型为MyException。另外捕捉异常catch块中应用了异常类型对象实例调用其what方法获取对应的异常信息并赋值最后输出。 主程序中从键盘输入两个整型数分别为12和0。定义Compute类对象实例通过实参初始化计算类数据成员随后调用其除法计算方法。除法计算方法中由于除数为0则抛出自定义异常类型同时传入异常错误信息随后catch块中捕获到对应类型异常内部则调用自定义异常类中what方法获取异常出错信息最后打印输出。 14.3.2  异常类的继承处理 异常机制在继承体系中依然可以很好的运用。最重要的是利用类继承体系与对应的虚拟方法实现异常的多态性。通过自定义异常类派生新的异常类除了包含基类基本异常处理方法还可以包含自定义添加新的异常处理方式。下面将会在上述实例中添加异常派生类。新的异常派生类不仅仅可以在异常处抛出对应的错误信息还可以支持错误代码及对应的信息。 /** * 实例chapter1406 * 源文件chapter1406_01.h * 异常继承类的封装 */ //异常处理类源文件chapter1406_01.h #ifndef EXCEPTION_H_ #define EXCEPTION_H_ #include iostream #include string using namespace std; //自定义异常类 class MyException { public: MyException()                                                 //自定义异常类构造函数定义 { m_context ;                                      //初始化类异常信息数据成员为空 } virtual~MyException(){}                               //异常类析构函数定义 MyException(const string right)              //异常类构造函数定义通过传入字符串型参数初始化 { m_context right; } MyException(const char * right)                 //异常类构造函数定义通过传入字符串指针参数初始化 { m_context right; } virtualstring what() const                                      //异常类中虚拟what接口方法定义获取异常信息 { returnm_context; }  protected: string   m_context;                               //异常类保护型数据成员表示异常信息内容 }; //异常派生类加入错误代码处理 class code_MyException : public MyException { public: code_MyException(interror_code, string error_code_msg , string context )//异常派生类构造 { m_errorCode error_code;                                                                       //错误代码初始化 m_errorCodeMsg error_code_msg;                                                     //错误代码对应消息初始化 m_context context;                                                                                             //对应异常信息初始化 } stringwhat() const                                                                                                 //派生类what接口重定义 { chartmp[20];                                                                                                  //定义临时字符数组 sprintf(tmp,%d, m_errorCode);                                                              //格式化错误代码 returnstring(tmp) , m_errorCodeMsg , m_context;             //返回连接的错误信息 } intgetErrorCode() const                                                                                      //获取错误代码 { returnm_errorCode; } stringgetErrorCodeMsg() const                                                                         //获取错误代码对应信息 { returnm_errorCodeMsg; } protected: int  m_errorCode;                                                                                                 //错误代码 string  m_errorCodeMsg;                                                                                             //错误信息 }; #endif 上述实例中在原来异常类的基础之上派生了新的异常处理类其中增加了错误代码以及错误信息的功能。利用C继承机制同时将其中的析构方法以及what接口定义为虚拟函数有助于统一接口的实现。封装实现的异常处理类可以将其编译为库作为系统中统一的组件供程序来使用。该实例的实际应用以及测试由初学者按照前面实例的方式来实践操作从中领悟C多态以及异常处理的好处。 14.4  标准库提供异常处理类 C标准库同样对异常作出了封装实现。标准库中异常实现也采用类继承层次式的结构。库中针对异常处理提供了一个层次化的类结构。该类层次中顶层基类为exception即针对其它不同情况下的异常处理类都派生自exception类。 针对异常处理总共提供了八个标准异常处理。其中四个针对语言级提供的抛出异常分别为bad_alloc、bad_cast、bad_typeid以及bad_exception另外四个为C标准库抛出的异常分别是out_of_range、invalid_argument、overflow_error以及ios_base::failure。下面将会针对这八类抛出异常情况作详细的讲述分别说明每类异常表达的意义及基本用法。 1. bad_alloc bad_alloc针对C中动态存储分配new的操作提供的异常信号主要针对分配内存空间时内存耗尽分配不足时抛出的异常。这种异常的抛出有利于开发者在实际应用中针对new操作分配内存时提供某种分配出错的处理方式。下面可以通过一个基本小代码片段来理解bad_alloc异常处理情况。 void newChar() { try { newchar[10000000000000];             //通过new开辟一个超大的内存空间 }catch(bad_alloc) { cout”memoryerror!”endl; } } 上述代码动态new了一个很大的内容空间当本地计算机内存不足时会默认抛出bad_alloc异常。随后catch捕捉到该异常后进入对应的异常处理块中。 2.bad_cast C多态提供的dynamic_cast应用于指针类型时通常需要考虑指针各类异常的情况。这时可以显式的去判断处理。但是当dynamic_cast应用于引用时即dynamic_castType(object)表示引用的类型为Type如果引用的不是对应类型的对象则dynamic_cast将会默认隐式的作断言检查。这时就会抛出bad_cast异常供catch捕获检测处理。 3. bad_typeid bad_typeid是针对dynamic_cast操作空指针抛出的异常。 4. bad_exception 当应用程序出现了无法catch捕获的异常情况时通常会调用terminate终止程序。而使用bad_exception时出现类似情况则会抛出bad_exception异常用来替代终止程序。 bad_exception异常处理则主要针对应用提出的。这些类同样从exception类派生而来。out_of_range表示操作数组等结构下标时访问超过设定范围所抛出的异常。它主要针对容器中at()方法与重载的下标访问运算符两类方法。invalid_argument则表示向函数传递无效参数时抛出的异常开发者可以针对该类抛出的异常作出相应的处理。overflow_error表示运算时候发生的上溢情况抛出的异常。ios_base::failure则是针对输出输入流操作时抛出的异常。 标准库中异常处理的封装可以通过查阅相关标准文档根据提供的相关处理接口在实际的应用程序中使用。实际的exception基类中除了基本的构造函数外重载实现一些运算符操作。最重要的是其what接口的定义该方法定义为虚拟方法供其派生类中改写增加更多的异常处理。 14.5  C应用程序错误处理 C应用软件系统开发中通常情况下可以通过实现错误处理类来记录程序启动以及处理中可能出现的错误情况。错误处理采用自定义类类型来实现除了起到异常处理的补充作用以外对于程序中必不可少的异常容错处理来讲错误处理相对效率较高些。下面本小节主要通过自定义实现一个错误处理类的实例详细讲述软件应用程序中针对错误处理的另外一种错误信息提示方式。 1.准备实例 打开UE工具创建新的空文件并另存为chapter1407_01.h、chapter1407_01.cpp、chapter1407_02.cpp。该代码文件随后会同makefile文件一起通过FTP工具传输至Linux服务器端客户端通过scrt工具访问操作。程序代码文件编辑如下所示。 //错误处理类头文件chapter1407_01.h #ifndef ERRORHANDLE_H_ #define ERRORHANDLE_H_ #include iostream #include string #include deque using namespace std; const int ERRORMSG_LEN 300;                                                            //错误信息长度常量定义 class ErrorInfo                                                                                               //错误信息类 { public: ErrorInfo(){}                                                                                 //错误信息空构造函数定义 ~ErrorInfo(){}                                                                               //错误信息空析构函数定义 ErrorInfo(constErrorInfo errorinfo);                                              //错误信息类拷贝构造 public: intm_errorNo;                                                                            //错误信息类数据成员表示错误代码 charm_message[ERRORMSG_LEN1];                              //错误信息类数据成员表示错误信息 }; class ErrorMessages                                                                                   //错误消息容器类 { public: voidsetProgramInfo(const string programInfoName);    //错误消息容器类设置应用程序信息方法 stringgetProgramInfo();                                                           //错误消息容器类获取应用程序信息方法 voidinsert(ErrorInfo errInfo);                                                 //错误消息容器类插入错误信息方法 boolget(ErrorInfo errInfo);                                                     //错误信息容器类获取错误信息方法 voidclean();                                                                                //清空错误消息队列方法 boolisEmpty();                                                                           //判断错误消息队列是否为空 voidinsert(const int errorCode, const string errorMessage);   //重载插入错误信息方法 voidinsert(const int errorCode, const char *errorMessage);      //重载插入错误信息方法 private: stringm_programInfoName;                                                   //错误消息类数据成员表示应用程序名 dequeErrorInfom_errorInfoQueue;                                  //错误消息类数据成员表述错误信息队列 }; #endif //错误处理类源文件chapter1407_01.cpp #include chapter1407_01.h ErrorInfo::ErrorInfo(const ErrorInfoerrorinfo)                                       //错误信息类拷贝构造定义 { m_errorNo errorinfo.m_errorNo;                                                  //拷贝传入错误信息类对象的成员 strcpy(m_message,errorinfo.m_message); } void ErrorMessages::setProgramInfo(conststring programInfoName)   //设置应用程序信息方法定义 { m_programInfoName programInfoName;                                          //根据传入的程序名设置 } string ErrorMessages::getProgramInfo()                                                 //获取应用程序信息 { returnm_programInfoName;                                                           //返回应用程序名称信息 } void ErrorMessages::insert(ErrorInfoerrorinfo)                                   //插入错误信息方法定义 { m_errorInfoQueue.push_back(errorinfo);                                               //将传入的错误信息类对象放入错误信息队列 } void ErrorMessages::insert(const int errorCode,const string errorMessage)//重载插入错误信息方法定义 { ErrorInfoerrorinfo;                                                                              //定义错误信息类对象实例 errorinfo.m_errorNo errorCode;                                                   //将传入的错误代码赋值给该对象中数据成员 if(errorMessage.length() ERRORMSG_LEN)                          //如果传入的错误信息长度在规定之内 strcpy(errorinfo.m_message,errorMessage.c_str());                  //则将错误信息拷贝到该对象对应数据成员中 else                                                                                                        //否则扩充长度后再拷贝 { strncpy(errorinfo.m_message,errorMessage.c_str(), ERRORMSG_LEN); errorinfo.m_message[ERRORMSG_LEN] 0; } insert(errorinfo);                                                                                   //最后插入到错误消息队列中 } void ErrorMessages::insert(const int errorCode,const char *errorMessage)//插入错误信息重载方法定义 { ErrorInfoerrorinfo;                                                                             //定义错误信息类对象 errorinfo.m_errorNo errorCode;                                                   //同上一方法定义 if(strlen(errorMessage) ERRORMSG_LEN) strcpy(errorinfo.m_message,errorMessage); else { strncpy(errorinfo.m_message,errorMessage, ERRORMSG_LEN); errorinfo.m_message[ERRORMSG_LEN] 0; } insert(errorinfo); } bool ErrorMessages::get(ErrorInfo errorinfo)                                       //获取错误信息队列中的信息 { if(m_errorInfoQueue.empty())                                                         //如果错误信息队列为空则直接返回false returnfalse; errorinfo m_errorInfoQueue.front();                                                      //返回队列中头部的数据 m_errorInfoQueue.pop_front();                                                                 //删除队列中头部的数据 returntrue; } void ErrorMessages::clean()                                                                      //清空错误信息队列 { m_errorInfoQueue.clear();                                                                          //直接调用clear方法清除 } bool ErrorMessages::isEmpty()                                                                           //判断错误信息是否为空 { returnm_errorInfoQueue.empty();                                                  //直接调用empty方法判断 } //错误处理类测试源文件chapter1407_02.cpp #include chapter1407_01.h ErrorMessages errorMessages;                                                                //定义错误消息容器类对象 const int E_DIVISOR_ZERO 200;                                                           //定义除数为0的错误代码常量 const string E_DIVISOR_ERROR divisor is0!;                                  //定义除数为0的错误信息常量 void divideCompute(int value1,int value2)                                                       //除法计算函数定义 { if(value2 0)                                                                                      //如果除数为0则记录相应的错误信息 { errorMessages.insert(E_DIVISOR_ZERO,E_DIVISOR_ERROR);//插入对应的错误代码与错误信息 } else                                                                                                        //否则计算除法并输出结果 { coutvalue1/value2:(value1/value2)endl; } } int main(int argc,char *argv[]) { stringname;                                                                                //定义字符串对象name ErrorInfoerrorInfo;                                                                     //定义错误信息类 name argv[0];                                                                                    //获取程序名并初始化字符串name errorMessages.setProgramInfo(name);                                //调用错误信息容器类中设置程序信息方法 coutProgramname:errorMessages.getProgramInfo()endl;//打印输出该程序信息 intvalue1,value2;                                                                       //定义两个整型变量 coutPleaseinput two value:endl;                                //提示输入两个整型参数 cinvalue1value2;                                                              //从键盘输入两个整型数 divideCompute(value1,value2);                                                       //调用计算除法运算的函数计算输入的数据 errorMessages.get(errorInfo);                                                 //获取错误消息队列中的数据 couterrorcode:errorInfo.m_errorNo errormessage:errorInfo.m_messageendl;          //打印输出对应队列中的错误信息 return0; } 本实例主要通过封装程序错误处理类演示应用程序中错误处理的一般实现方式。程序主要由错误处理类与主函数组成程序具体剖析见程序注释与后面的讲解。 2.编辑makefile Linux平台下需要编译源文件为chapter1407_01.cpp、chapter1407_02.cpp相关makefile工程文件编译命令编辑如下所示。 OBJECTSchapter1407_01.o chapter1407_02.o CCg chapter1407_02: $(OBJECTS) $(CC)$(OBJECTS) -g -o chapter1407_02 chapter1407_01.o:chapter1407_01.h chapter1407_02.o: clean: rm-f chapter1407_02 core $(OBJECTS) submit: cp-f -r chapter1407_02 ../bin cp-f -r *.h ../include 上述makefile文件套用前面的模板格式主要替换了代码文件、程序编译中间文件、可执行程序等。在编译命令部分-g选项的加入表明程序编译同时加入了可调式信息。 3.编译运行程序 当前shell下执行make命令生成可执行程序文件随后通过make submit命令提交程序文件至本实例bin目录通过cd命令定位至实例bin目录执行该程序文件运行结果如下所示。 [developerlocalhost src]$ make g    -c -ochapter1407_01.o chapter1407_01.cpp g    -c -ochapter1407_02.o chapter1407_02.cpp g chapter1407_01.o chapter1407_02.o -g -ochapter1407_02 [developerlocalhost src]$ make submit cp -f -r chapter1407_02 ../bin cp -f -r *.h ../include [developerlocalhostsrc]$ cd ../bin [developerlocalhostbin]$ ./chapter1407_02 Program name:./chapter1407_02 Please input two value: 12 0 error code:200 error message:divisor is 0! 本实例中主要定义实现错误处理类。该类用于记录软件系统中自定义的错误代码与对应的错误信息以配合异常实现应用程序相应的错误处理。上述实例中错误处理主要涉及两个类的定义 q  一个为记录错误信息类ErrorInfo。其中主要包括相应的构造析构函数以及一个错误信息对象拷贝方法。它还包含两个公开的数据成员用于分别表示错误代码与对应的错误信息。 q  另一个为错误信息容器类ErrorMessage。该类主要用于记录并存放相应的错误处理信息并提供相应的错误信息访问接口以供应用程序使用。 ErrorMessage类中主要包括八个接口方法与两个数据成员。该类的接口方法在注释中作了详细的标注。其中这些接口中最重要为几个insert方法的重载实现从而实现了不同种情况下的信息插入处理。第一个是整个结构体对象参数接口第二个为支持错误代码与字符串类型的对象接口最后一个为支持错误代码与字符串常量的插入信息接口。其中还包括两个保护数据成员分别为应用程序名称m_programInfoName和存放错误消息的队列m_errorInfoQueue。该队列中存放的为错误信息类类型的数据。 主程序中则仍然主要以测试除法运算中除数为0时的错误处理。首先从程序信息argv参数数组中获取程序名称设置并获取打印该信息。随后根据传入的两个整型数调用对应的计算除法的运算方法。该方法中一旦除数为0则记录对应的错误信息。最后主程序中则获取到对应的错误信息并打印输出。 上述程序中错误处理类可以放入自定义库或者组件中供应用程序中记录错误信息使用。其中支持错误代码以及对应的错误信息对应记录。这样做的好处是针对不同的模块设计可以规定一套错误代码以及对应信息供整个系统使用。另外插入的错误信息可以根据实际需求将其记录到日志文件中供出现错误时查询使用。 14.6  小结 C异常处理的提出为编写出更具健壮性、稳定性的应用程序提供了很好的支持。但是异常与前面介绍该语言的特性一样不能够滥用。因为任何支持的特性总是以牺牲一定的效率来实现的。通过上述介绍用户在实际软件系统中可以结合错误处理、异常以及对应的错误日志等最终开发出高稳定、高容错性的应用系统。
http://www.pierceye.com/news/817753/

相关文章:

  • 响应式电商网站制作企业咨询诊断报告
  • 企业网站怎么建设公司展厅装修设计
  • 怎么联系网站管理员怎么做拍卖网站
  • 山东威海网站开发长沙新媒体运营公司
  • 社保网站做员工用工备案wordpress登录查看
  • 做网站公司名字应该用图片吗沃尔玛公司网站建设案例分析
  • 网站空间大小多少合适做关于车的网站
  • 专注咖啡相关的网站wordpress 访问缓慢
  • 自适应网站制作官网网站域名与建设
  • 淘宝网站开发成本武进建设局网站进不去
  • 比较好网站制作公司行业协会网站织梦模板
  • 牛人网络网站像wordpress一样的网站吗
  • 那种做任务的网站叫什么wordpress 数据库 旧Ip
  • 制作深圳网站建设百度推广广告收费标准
  • 电影采集网站建设国产做爰全免费的视频网站
  • 集团网站建设特点 助君长春seo公司网站
  • 网站域名备案 更改吗在线做文档的网站
  • 青海网站制作多少钱做网站教程pdf
  • dw做网站背景音乐wordpress 获取当前文章id
  • 上海鹭城建设集团网站icp备案查询
  • 企业站用什么程序做网站深圳手机报价网站
  • 网站开发国外研究状况建设部相关网站
  • 租赁网站开发台州网站优化
  • 网站开发人员工工资网站开发一个支付功能要好多钱
  • 工程建设管理网站源码网站怎样做地理位置定位
  • 太仓公司网站建设电话网络公关名词解释
  • 江门网站建设策划什么是网络营销职能
  • 北京网站托管毕设做网站是不是太low
  • 企业网站建设费用属管理费用吗重庆网站建设制作设计公司哪家好
  • 深圳营销型网站需要多少钱做网站个体户经营范围