11. C++异常处理
什么是异常处理
异常: 任何事物,任何情况都可以当做异常,错误算是异常的一种
异常处理机制: 暂时性不做处理,抛出异常,留给使用者去处理
注意问题: 所有抛出的异常,必须要处理,如果不做处理,引发异常识,程序调用abort函数终止程序
异常处理基操
抛出异常: throw 抛出的东西一定一个值
检查异常:try
捕获处理异常:catch
注意点: try和catch必须一起出现,并且各自的{}不能省略
#include <iostream>
using namespace std;
int Div(int a, int b)
{
//正常写程序 有问题立刻处理
//if (b == 0)
//{
// cout << "除数不能为0" << endl;
// return 0;
//}
if (b == 0)
throw 0;
return a / b;
}
int main()
{
//Div(1, 0); //调用abort函数终止程序
try
{
cout << "测试.....1" << endl;
Div(1, 0);
cout << "测试.....2" << endl;
}
catch (double) //捕获int类型异常
{
cout << "double:除数不能为零" << endl;
}
catch (int)
{
cout << "int:除数不能为零" << endl;
}
//error C2312: “int”: 由“int”在行 28 上捕获
//catch (int)
//{
//cout << "int:除数不能为零" << endl;
//}
return 0;
}
没有异常
老版本: throw () 放在函数后面
新标准: noexcept放在函数后面修饰
//老版本
int Max(int a, int b) throw()
{
return a > b ? a : b;
}
//新标准
int Sum(int a, int b) noexcept
{
return a + b;
}
异常处理的传参操作
#include <iostream>
using namespace std;
void printArray(int array[], int arrayNum)
{
if (arrayNum < 1)
throw 1;
cout << "正常长度,假装打印...." << endl;
}
void searchArray(int array[], int arrayNum)
{
if (arrayNum < 1)
throw 2;
cout << "正常长度,假装查找...." << endl;
}
void deleteArray(int array[], int arrayNum)
{
if (arrayNum < 1)
throw 3;
cout << "正常长度,假装删除...." << endl;
}
int Div(int a, int b)
{
if (b == 0)
throw string("除数不能为零");
return a / b;
}
//抛出自己类对象:自定义异常类
class stackEmpty
{
public:
stackEmpty(string strInfo) :strinfo(strInfo) {}
void print()
{
cout << "error:" << strinfo << endl;
}
private:
string strinfo;
};
//假装入栈
void push(int a)
{
if (a == 0)
throw stackEmpty("栈为空");
cout << a << endl;
}
int main()
{
try
{
int array[3] = { 1,2,3 };
printArray(array, 3);
searchArray(array, -1);
deleteArray(array, 2);
}
catch (int value) //int value=抛出的值
{
switch (value)
{
case 1:
cout << "打印异常" << endl;
break;
case 2:
cout << "查找异常" << endl;
break;
case 3:
cout << "删除异常" << endl;
break;
}
}
try
{
cout << Div(2, 1) << endl;
cout << Div(2, 0) << endl;
}
catch (string& object)
{
cout << object << endl;
}
//... 表示可以捕获任何异常
try
{
cout << Div(2, 0) << endl;
}
catch (...) //删减符
{
cout << "引发异常" << endl;
}
try
{
push(1233);
push(0);
}
catch (stackEmpty& object)
{
object.print();
}
return 0;
}
标准库中的异常
C++ 提供了一系列标准的异常,定义在 中,我们可以在程序中使用这些标准的异常。它们是以父子类层次结构组织起来的,如下所示:
下表是对上面层次结构中出现的每个异常的说明:
标准库中异常
exception类组成:
- what方法 用来返回异常信息的字符串
#include <exception>
#include <iostream>
using namespace std;
class Error :public exception
{
public:
//virtual char const* what() const
//{
// return "Error";
//}
Error() :exception("Error") {}
private:
};
void printTest()
{
throw Error();
}
int main()
{
try
{
printTest();
}
catch (Error& object)
{
cout << object.what() << endl;
}
return 0;
}
引发ball_alloc异常
#include <exception>
#include <iostream>
using namespace std;
int main()
{
int array[3] = { 1,2,3 };
try
{
while (1)
{
int* p = new int[1024 * 1024];
}
}
catch (bad_alloc& object)
{
cout << object.what() << endl;
}
return 0;
}
异常处理的建议
- 局部控制能处理的问题,不需要异常机制
- 千万不要在析构函数抛出异常(作死操作)
- 构造函数存在问题,也不要次啊用异常机制
- 自己写异常类 没必要都是继承exception,可以适当根据具体问题,继承相应子类即可