(一)异常处理定义
异常是程序在执行期间产生的问题,任何事物,任何情况都可以当做异常,错误算是异常的一种 。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。
异常处理机制: 暂时性不做处理,抛出异常,留给使用者去处理。
异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw。
标准库中的异常:
注意: 所有抛出的异常,必须要处理,如果不做处理,引发异常识,程序调用abort函数终止程序
(二)异常处理基操
抛出异常: throw 抛出的东西一定是一个值
检查异常:try:try块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。
捕获处理异常:catch在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。
try和catch必须一起出现,并且各自的{}不能省略
基本语法格式:try { // 保护代码 }catch(...) { // 能处理任何异常的代码 }
如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码。
相关代码:
#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)
{
cout << "double:除数不能为零" << endl;
}
catch (int) //捕获int类型异常
{
cout << "int:除数不能为零" << endl;
}
//error C2312: “int”: 由“int”在行 28 上捕获,不能写两个相同的
//catch (int)
//{
//cout << "int:除数不能为零" << endl;
//}
return 0;
}
(三) C++ 标准的异常
C++ 提供了一系列标准的异常,定义在 <exception> 中,我们可以在程序中使用这些标准的异常。它们是以父子类层次结构组织起来的,如下所示:
下表是对上面层次结构中出现的每个异常的说明:
异常 | 描述 |
---|---|
std::exception | 该异常是所有标准 C++ 异常的父类。 |
std::bad_alloc | 该异常可以通过 new 抛出。 |
std::bad_cast | 该异常可以通过 dynamic_cast 抛出。 |
std::bad_exception | 这在处理 C++ 程序中无法预期的异常时非常有用。 |
std::bad_typeid | 该异常可以通过 typeid 抛出。 |
std::logic_error | 理论上可以通过读取代码来检测到的异常。 |
std::domain_error | 当使用了一个无效的数学域时,会抛出该异常。 |
std::invalid_argument | 当使用了无效的参数时,会抛出该异常。 |
std::length_error | 当创建了太长的 std::string 时,会抛出该异常。 |
std::out_of_range | 该异常可以通过方法抛出,例如 std::vector 和 std::bitset<>::operator[]()。 |
std::runtime_error | 理论上不可以通过读取代码来检测到的异常。 |
std::overflow_error | 当发生数学上溢时,会抛出该异常。 |
std::range_error | 当尝试存储超出范围的值时,会抛出该异常。 |
std::underflow_error | 当发生数学下溢时,会抛出该异常。 |
exception类组成:
-
what方法 用来返回异常信息的字符串
相关代码:
#include <iostream>
#include <exception>
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;
}
(四)异常处理的小技巧
局部控制能处理的问题,不需要异常机制
千万不要在析构函数抛出异常(作死操作)
构造函数存在问题,也不要次啊用异常机制
自己写异常类 没必要都是继承exception,可以适当根据具体问题,继承相应子类即可