概念:
函数是一种以栈结构展开的上下函数衔接的程序控制系统
,异常是另一种控制结构,
它可以在出现“意外”时中断当前函数,
并以某种机制(类型匹配)回馈给隔代的调用者相关的信息.
异常处理的基本语法
异常发生第一现场,抛出异常,中断程序
void function( ){
//... ...
throw 表达式
;//... ...
}
在需要关注异常的地方,捕捉异常
try{
//程序
function();
//程序
}catch(
异常类型声明
){//... 异常处理代码
...}catch(
异常类型 形参
){//... 异常处理代码
...}catch(...){ //
其它异常类型//
}
①
通过
throw 操作创建一个异常对象并抛掷②
在需要捕捉异常的地方,将
可能抛出异常的程序段嵌在 try
块之中③按正常的程序顺序执行到达
try
语句,然后执行
try
块
{}
内的保护段,如果
有匹配的时候才会执行catch
语句抛出异常,中断程序(以函数体为单位)④如果没有找到匹配,则
缺省功能是调用 abort 终止
程序。
int
copyfile2(
char
*dest,
char
*src){FILE *fp1 = NULL, *fp2 = NULL;
//rb 只读方式打开一个二进制文件,只允许读取数据
fopen_s(&fp1, src,
"rb"
);if
(fp1 == NULL){throw
new string
(
"文件不存在"
);//这里抛出一个指针}
fopen_s(&fp2, dest,
"wb"
);if
(fp2 == NULL){throw
-2;}
}
int main(void){
int
ret = 0;try
{ret = copyfile1(
"c:/test/dest.txt"
,
"c:/test/src.txt"
);}
catch
(
int
error){ //catch(int)只接受到int值printf(
"出现异常啦!%d
"
, error);}
catch
(string *error){
//用指针接收stringprintf(
"捕捉到字符串异常:%s
"
, error->c_str());delete
error;}
}
异常接口声明
int copyfile2(char *dest, char *src) throw (float, string *, int)
在函数声明中列出可能抛出的所有异常类型,,,没有包含异常接口声明,此函数可以抛出任何类型的异常.如果产生异常声明之外的其它类型的异常就可能导致程序终止.
如果不想抛出任何异常,那么就使用throw();
异常类型和生命周期
异常基础类型:
catch (int error) {
printf("出现异常啦!%d
", error);
}
catch (char error) {
printf("出现异常啦!%c
", error);
}
异常字符串类型
if
(fp1 == NULL){throw new
string(
"文件不存在"
);}
catch
(string *error){printf(
"捕捉到字符串异常:%s
"
, error->c_str());delete
error;}
异常类类型
if
(fp1 == NULL){//ErrorException error1;
throw
ErrorException();
//throw ErrorException();//指针 throw new
ErrorException();}
catch
(ErrorException &error){//error.id = 2;
printf(
"出现异常啦!捕捉到 ErrorException &类型 id: %d
"
,error.id);
}
catch
(ErrorException *error){printf(
"出现异常啦!捕捉到 ErrorException *类型 id: %d
"
,error->id);
delete
error;}
异常和继承练习(使用多态)
案例:设计一个数组类容器
Vector
,重载
[]
操作,数组初始化时,对数组的个数进行有效检查
1
)
index<0
抛出异常
errNegativeException2
)
index = 0
抛出异常
errZeroException3
)
index>1000
抛出异常
errTooBigException4
)
index<10
抛出异常
errTooSmallException5)
errSizeException
类是以上类的父类,实现有参数构造、并定义
virtual void printError()
#include <iostream> using namespace std; /* 1)index<0 抛出异常 errNegativeException 2)index = 0 抛出异常 errZeroException 3)index>1000 抛出异常 errTooBigException 4)index<10 抛出异常 errTooSmallException 5) errSizeException 类是以上类的父类,实现有参数构造、并定义 virtual void printError() */ class errSizeException { public: errSizeException(int len) { this->len = len; }; virtual void printError() { cout << "errSizeException:size:" << len << endl; }; protected: int len; }; //index<0 class errNegativeException:public errSizeException { public: //errNegativeException(); errNegativeException(int len):errSizeException(len){}; virtual void printError() { cout << "errNegativeException:size:" << len << endl; }; }; //index = 0 class errZeroException :public errSizeException { public: //errZeroException(); errZeroException(int len) :errSizeException(len) {}; virtual void printError() { cout << "errZeroException:size:" << len << endl; }; }; //index>1000 class errTooBigException :public errSizeException { public: //errTooBigException(); errTooBigException(int len) :errSizeException(len) {}; virtual void printError() { cout << "errTooBigException:size:" << len << endl; }; }; //index<10 class errTooSmallException :public errSizeException { public: //errTooSmallException(); errTooSmallException(int len) :errSizeException(len) {}; virtual void printError() { cout << "errTooSmallException:size:" << len << endl; }; }; class Vector { public: //构造函数 Vector(int len) { if (len<0){ throw errNegativeException(len); } else if (len == 0) { throw errZeroException(len); } else if (len > 1000) { throw errTooBigException(len); } else if (len < 10) { throw errTooSmallException(len); } this->len = len; m_len = new int(len); } int getLen() { return len; } //析构函数 ~Vector() { if (!m_len){ delete[] m_len; m_len = NULL; len = 0; } } //下标运算符重载 int& operator[](int dex) { return m_len[dex]; } private: int len; int* m_len; }; int main(void) { try{ Vector aa(-10); for (int i = 0; i < aa.getLen(); i++){ aa[i] = i; } } catch(errSizeException err){ err.printError(); } /*catch (errNegativeException &err){ cout << "errNegativeException:size" << endl; }*/ }
C++标准库的各类异常所代表的异常
谨慎尝试以下代码:
#include <iostream> #include <exception> #include <stdexcept> using namespace std; class Student { public: Student(int age) { if (age > 249) { throw out_of_range("年龄太大,你是外星人嘛?"); } m_age = age; m_space = new int[1024 *1024 * 100]; } private: int m_age; int* m_space; }; void main() { try { for (int i = 1; i < 1024; i++) { Student* xiao6lang = new Student(18); } } catch (out_of_range& e) { cout << "捕捉到一只异常:" << e.what() << endl; } catch (bad_alloc& e) { cout << "捕捉到动态内存分配的异常:" << e.what() << endl; } system("pause"); }