异常处理的基本思想
异常处理机制
-
异常无处不在,程序随时可能误入歧途!C++ 提出了新的异常处理机制!
-
异常是一种程序控制机制,与函数机制互补
-
函数是一种以栈结构展开的上下函数衔接的程序控制系统,异常是另一种控制结构,它可以在出现“意外”时中断当前函数,并以某种机制(类型匹配)回馈给隔代的调用者相关的信息.
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
#define BUFSIZE 1024
//实现文件的二进制拷贝
int copyfile2(const char* dest, const char* src) {
FILE* fp1 = NULL, * fp2 = NULL;
//rb 只读方式打开一个二进制文件,只允许读取数据
fopen_s(&fp1, src, "rb");
if (fp1 == NULL) {
throw new string("文件不存在");
}
//wb 以只写的方式打开或新建一个二进制文件,只允许写数据。
fopen_s(&fp2, dest, "wb");
if (fp2 == NULL) {
throw - 2;
}
char buffer[BUFSIZE];
int readlen, writelen;
//如果读到数据,则大于0
while ((readlen = fread(buffer, 1, BUFSIZE, fp1)) > 0) {
writelen = fwrite(buffer, 1, readlen, fp2);
if (readlen != writelen) {
throw - 3;
}
}
fclose(fp1);
fclose(fp2);
return 0;
}
int copyfile1(const char* dest, const char* src) {
try{
copyfile2(dest, src);
} catch(float e) {
printf("copyfile1 - catch ...\n");
//提示:处理不了的异常,我们可以在catch的最后一个分支,使用throw语法,继续向调用者throw。
throw ;
}
return 0;
}
void main(){
int ret = 0;
//在需要捕捉异常的地方,将可能抛出异常的程序段嵌在try块之中
//按正常的程序顺序执行到达try语句,然后执行try块{}内的保护段
//如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行,程序从try块后跟随的最后一个catch子句后面的语句继续执行下去
try{//保护段
printf("开始执行 copyfile1...\n");
ret = copyfile1("c:/test/dest.txt", "c:/test/src.txt");
printf("执行 copyfile1 完毕\n");
//catch子句按其在try块后出现的顺序被检查,匹配的catch子句将捕获并按catch子句中的代码处理异常(或继续抛掷异常)
}catch(int error){
printf("出现异常啦!%d\n", error);
}catch(string *error){
printf("捕捉到字符串异常:%s\n", error->c_str());
delete error;
}catch(float error){
printf("出现异常啦!%f\n", error);
}catch(...){
printf("catch ...\n");
}
//如果没有找到匹配,则缺省功能是调用abort终止程序。
system("pause");
}
异常处理基本语法
异常发生第一现场,抛出异常
void function( ) {
//... ...
throw 表达式;
//... ...
}
在需要关注异常的地方,捕捉异常
try{
//...程序
function();
//...程序
} catch(异常类型声明) {
//... 异常处理代码 ...
} catch(异常类型 形参) {
//... 异常处理代码 ...
} catch(...) { //其它异常类型
//...
}
注意事项:
- 通过 throw 操作创建一个异常对象并抛掷
- 在需要捕捉异常的地方,将可能抛出异常的程序段嵌在 try 块之中
- 按正常的程序顺序执行到达 try 语句,然后执行 try 块 {} 内的保护段
- 如果在保护段执行期间没有引起异常,那么跟在 try 块后的 catch 子句就不执行,程序从 try 块后跟随的最后一个 catch 子句后面的语句继续执行下去
- catch 子句按其在 try 块后出现的顺序被检查,匹配的 catch 子句将捕获并按 catch 子句中的代码处理异常(或继续抛掷异常)
- 如果没有找到匹配,则缺省功能是调用 abort 终止程序。
提示:处理不了的异常,我们可以在 catch 的最后一个分支,使用 throw 语法,继续向调用者 throw 。
异常接口声明
可以在函数声明中列出可能抛出的所有异常类型,加强程序的可读性。
如:
int copyfile2(char *dest, char *src) throw (float, string *, int)
1.对于异常接口的声明,在函数声明中列出可能抛出的所有异常类型
2.如果没有包含异常接口声明,此函数可以抛出任何类型的异常
3.如果函数声明中有列出可能抛出的所有异常类型,那么抛出其它类型的异常讲可能导致程序终止
4.如果一个函数不想抛出任何异常,可以使用 throw () 声明