Try-Catch 执行机制
将可能抛出异常的程序段嵌在 try 块保护段之中。控制通过正常的顺序执行到达 try块,然后执行 try 子块内的保护段。如果在保护段执行期间没有引发异常,那么跟在try子块后的catch子句就不执行。程序会继续执行紧跟在try块中最后一个catch子句后面的语句。
若程序有异常,则通过 throw 关键字创建一个异常对象,并抛出。
catch子句按其在try块后出现的顺序被检查。类型匹配的catch子句将捕获throw抛出的对象并处理异常(或继续抛出异常)。
如果找不到匹配的处理代码,则自动调用标准库函数terminate,其默认功能是调用abort( ) 终止程序。
try块
我们只需将可能有问题的代码块放入try块中,若有问题则会抛出异常,try块会停止运行
try{
可能有问题的代码
}
throw关键字
throw 表达式;
throw; //用于当前异常再抛出
throw std::out_of_range("Index out of range");
在throw后面接上异常的类型,然后在括号内写下想输出的字符串
try {
...
} catch (const std::out_of_range& e) {
cout << e.what();
}
若try中出现异常就会输出该字符串
Index out of range
catch
catch紧接着try块写,将会捕捉类型相同的异常
catch (std::bad_alloc& ba)
{
std::cerr << "bad_alloc caught: " << ba.what() << '\n';
}
cerr是用于异常的输出,这里用cout也行
catch括号内首先说明异常的类型,并注意这里要使用异常对象的引用!
但是异常的种类实在太多了,我们一个个写的话太麻烦了,catch还提供一种模式
catch (...)
{
...
}
在括号内写三个"."表示所有类型的异常,该catch可以捕获所有类型的异常,所以必须是最后的catch。
在catch捕获的顺序中,子类应该在基类前面
异常传播
在函数调用的时候,若当前函数未处理异常(catch没有相符合的类型),则会将该异常交给调用函数
void f3(int x) {
switch (x) {
case 1: throw 3.4; // 抛出double型异常
case 2: throw 2.5f; // 抛出float型异常
case 3: throw 1; // 抛出int型异常
case 5: throw exception(); //抛出标准异常
}
cout << "End of f3" << endl;
}
void f2(int x) {
try {
f3(x);
}
catch (int) { //int型异常的处理代码
cout << "An int exception occurred!--from f2" << endl;
}
catch (float) { //float型异常的处理代码
cout << "A float exception occurred!--from f2" << endl;
}
cout << "End of f2" << endl;
}
void f1(int x) {
try {
f2(x);
}
catch (int) { // int型异常的处理代码
cout << "An int exception occurred!--from f1" << endl;
}
catch (float) { // float型异常的处理代码
cout << "A float exception occurred!--from f1" << endl;
}
catch (double) { // double型异常的处理代码
cout << "A double exception occurred!--from f1" << endl;
}
cout << "End of f1" << endl;
}
int main()
{
for (int i = 1; i < 6; i++) {
cout << "-------- intput i = " << i << endl;
f1(i);
}
cout << "End of main" << endl;
return 0;
}
执行上面的代码我们会得到这样的输出
-------- intput i = 1
A double exception occurred!--from f1
End of f1
-------- intput i = 2
A float exception occurred!--from f2
End of f2
End of f1
-------- intput i = 3
An int exception occurred!--from f2
End of f2
End of f1
-------- intput i = 4
End of f3
End of f2
End of f1
-------- intput i = 5
terminate called after throwing an instance of 'std::exception'
what(): std::exception
可以看见,f2没有double型,所以将异常传递给了f1,因此没有输出“End of f2”