C++异常处理
一、基本的异常处理
1.异常处理机制
- 暂缓问题处理,不在当前函数中处理,在它调用者中处理
2.什么是异常处理
- 任何东西都可以当做异常,错误只是异常中的一种
- 异常一旦被抛出,不作处理,如果引发异常,会调用默认abort终止程序
3.捕捉和处理异常
- throw抛出异常,(可以理解为返回值,值是任何类型都可以,使我们处理异常一个参照)
- try(检查、捕获异常)和catch(处理异常)
try与catch必须是一起出现,并且他们之间的括号{}不能省略
try
{
//正常检查是否存在异常代码
}
catch(类型) //理解为switch中case语句
{
//处理是根据抛出数据类型决定如何处理
}
//一个try可以对应多个catch
try
{
//…
}
catch(int)
{}
catch(double)
{}
catch(string)
{}
- try与catch和if else_if执行机制是一样的,只能执行一个匹配项
- 删减符… 任何类型的异常都可捕获
- catch(…)
#include <iostream>
using namespace std;
int divisor(int a, int b)
{
if (b==0) //什么是异常
throw 0; //什么是抛出
return a / b;
}
void print(int a,int b)
{
cout << divisor(a, b);
}
int main()
{
try
{
print(1, 0);
//cout << "别的代码" << endl; 不会运行此列直接跳转到catch()
}
catch (int)
{
cout << "除数不能为零" << endl;
}
//catch (...)
//{
// cout << "任何类型一场都捕获" << endl;
//}
//print(1, 0); //引发异常不作处理
while (1);
return 0;
}
运行结果:
4.不存在异常的描述
- throw()
- noexcept()
void print() throw()
{
cout << “当前函数不存在抛出异常操作” << endl;
}
void printData() noexcept
{
cout << “新的描述:不存在抛出异常” << endl;
//throw 0; 编译不过,一旦说明没有异常操作,就不能抛出
}
二、异常处理中的传参
- catch(int a) //隐藏一个传参操作
- 想要处理抛出字符串的异常处理,注意一下string类型与const char* 类型的区别
- 也可以抛出自己类的对象
#include <iostream>
#include <string>
using namespace std;
class Error
{
public:
Error(const char* str = "未知错误") :str(str) {}
const char* what()const
{
return str.c_str();
}
protected:
string str;
};
int divisor(int a, int b)
{
if (b == 0)
throw "除数不能为0";
if (b == 1)
throw "除数不能为1";
if (b == 2)
throw string("除数不能为2");
return a / b;
}
void insertArray(int array[], int* curNum, int posData, int maxLength)
{
if (*curNum >= maxLength) //3>=3
{
throw Error("数组下标溢出!");
}
//0 1 2
array[*curNum] = posData; //array[3]=3
(*curNum)++;
}
//void print() throw()
//{
// cout << "当前函数不存在抛出异常操作" << endl;
//}
//void printData() noexcept
//{
// cout << "新的描述:不存在抛出异常" << endl;
// //throw 0; 编译不过,一旦说明没有异常操作,就不能抛出
//}
int main()
{
try
{
divisor(1, 0);
}
catch (const char* str) //str= "除数不能为零";
{
cout << str << endl;
}
try
{
divisor(1, 2);
}
catch (string str)
{
cout << str << endl;
}
try
{
int array[3] = { 0, 0, 0 };
int curNum = 0;
for (int i = 0; i < 4; i++)
{
insertArray(array, &curNum, i, 3);
}
}
catch (Error str)
{
cout << str.what() << endl;
}
while (1);
return 0;
}
运行结果:
三、自定义异常类
- 写一个类描述异常
- 继承标准库中的类描述异常
#include <iostream>
#include <string>
using namespace std;
//自己写的异常描述类
class Error
{
public:
Error(const char* str = "未知错误") :str(str) {}
const char* what()const
{
return str.c_str();
}
protected:
string str;
};
void insertArray(int array[], int* curNum, int posData, int maxLength)
{
if (*curNum >= maxLength) //3>=3
{
throw Error("数组下标溢出!");
}
//0 1 2
array[*curNum] = posData; //array[3]=3
(*curNum)++;
}
void testOne()
{
try
{
int array[3] = { 0,0,0 };
int curNum = 0;
for (int i = 0; i < 4; i++)
{
insertArray(array, &curNum, i, 3);
}
}
catch (Error str)
{
cout << str.what() << endl;
}
}
//继承标准库中的异常类
//通过重写what方法
class myException :public exception
{
public:
myException(string str) :exception(str.c_str()) {}
};
void insertArray(int a)
{
if (a >= 4)
throw myException("数组满了!");
cout << "插入成功" << endl;
}
void deleteArray(int a)
{
if (a <= 0)
throw myException("数组为空,无法删除");
cout << "删除成功" << endl;
}
void testTwo()
{
try
{
insertArray(1);
insertArray(4);
}
catch (myException& object)
{
cout << object.what() << endl;
}
try
{
deleteArray(1);
deleteArray(0);
}
catch (myException& object)
{
cout << object.what() << endl;
}
}
int main()
{
testOne();
testTwo();
return 0;
}
四、标准库中的异常
#include <exception>
#include <iostream>
using namespace std;
class Exception
{
public:
Exception(const char* ptr="UNKNOW") :ptr(const_cast<char*>(ptr)){}
virtual const char* what() const
{
return ptr;
}
protected:
char* ptr;
};
class Bad_alloc :public Exception
{
public:
Bad_alloc(const char* _Message = "bad exception") :Exception(_Message) {}
protected:
};
class Run_time :public Exception
{
public:
Run_time(const char* _Message = "run_time error") :Exception(_Message) {}
protected:
};
int main()
{
try
{
while (1)
{
int* p = new int[1024*1024*10];
}
}
catch (bad_alloc& object)
{
cout << object.what() << endl;
}
return 0;
}