本文内容来自于对狄泰学院 唐佐林老师 C++深度解析 课程的学习总结
- catch 语句块中可以抛出异常
- catch 中捕获的异常可以被重新解释后抛出
- 工程开发中使用这样的方式 统一异常类型
编程实验
下面我们来写一个程序对 catch 抛出的异常进行重新解释
#include <iostream>
using namespace std;
void func(int i)
{
if (i < 0)
{
//cout << "Inval param" << endl;
throw -1;
}
else if (i > 20)
{
//cout << "Out of range" << endl;
throw -2;
}
else if (i == 10)
{
//cout << "Error param" << endl;
throw -3;
}
}
void MyFunc(void)
{
try
{
func(10);
}
catch (int i)
{
if (i == -1)
throw "Inval param";
else if (i == -2)
throw "Out of range";
else if (i == -3)
throw "Error param";
}
}
int main()
{
try
{
MyFunc();
}
catch (const char *str)
{
cout << str << endl;
}
return 0;
}
运行结果:
实验结果,我们可以对 catch 抛出的异常进行捕获
异常类的自定义
异常的类型可以是 自定义类类型
对于类类型异常的匹配依旧是 至上而下严格匹配
赋值兼容性原则 在异常匹配中依然适用
一般而言
- 匹配子类异常的 catch 放在上部
- 匹配父类异常的 catch 放在下部
在工程中会定义 一系列的异常类
每个类代表工程中可能出现的一种异常类型
代码复用时 可能需要 重解释不同的异常类
在定义 catch 语句块时 推荐使用引用作为参数
实验编程
创建一个异常类来保存和捕获异常信息
#include <iostream>
using namespace std;
class Exception
{
int m_id;
string m_message;
public:
Exception(int id, string message)
{
m_id = id;
m_message = message;
}
int id()
{
return m_id;
}
string message()
{
return m_message;
}
void print_exception() const
{
cout << "Exception: id = " << m_id << ", message: " << m_message << endl;
}
};
void func(int i)
{
if(i<0)
throw Exception(-1, "Inval param");
else if( i > 100)
throw Exception(-2, "Out of range");
else if(i == 50)
throw Exception(-3, "Error param");
}
int main(void)
{
try
{
func(50);
}
catch(const Exception& e)
{
e.print_exception();
}
return 0;
}
运行结果:
C++ 标准库中提供了实用异常类族
标准库中的异常都是从 exception 类派生的
exception 类有两个主要的分支
logic_error
- 常用于程序中的可避免逻辑错误
runtime_error
- 常用于程序中无法避免的恶性错误
标准库中的异常
编程实验
标准库中的异常使用
#include <iostream>
using namespace std;
void func(int i)
{
if(i<0)
throw invalid_argument("i<0 invalid argument");
else if(i>=100)
throw out_of_range("i>100 out of range");
}
int main(void)
{
try
{
func(100);
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
}
运行结果:
小结
catch 语句块中可以抛出异常
异常的类型可以是 自定义类类型
赋值兼容性原则 在异常匹配中依然适用
标准库中的异常都是从 exception 类派生的