C++ try throw catch
基本思想:
函数 A 在执行过程中发现异常时可以不加处理,而只是“拋出一个异常”给 A 的调用者,假定为函数 B。
拋出异常而不加处理会导致函数 A 立即中止,在这种情况下,函数 B 可以选择捕获 A 拋出的异常进行处理,也可以选择置之不理。
如果置之不理,这个异常就会被拋给 B 的调用者,以此类推。
如果一层层的函数都不处理异常,异常最终会被拋给最外层的 main 函数。
main 函数应该处理异常。如果main函数也不处理异常,那么程序就会立即异常地中止。
C++异常处理基本语法
throw 语句的语法如下:
throw 表达式;
try...catch 语句的语法如下:
try {
语句组
}
catch(异常类型) {
异常处理代码
}
...
catch(异常类型) {
异常处理代码
}
catch 可以有多个,但至少要有一个。
把 try 和其后{}
中的内容称作“try块”,把 catch 和其后{}
中的内容称作“catch块”。
try...catch 语句的执行过程是:
执行 try 块中的语句,如果执行的过程中没有异常拋出,那么执行完后就执行最后一个 catch 块后面的语句,所有 catch 块中的语句都不会被执行;
如果 try 块执行的过程中拋出了异常,那么拋出异常后立即跳转到第一个“异常类型”和拋出的异常类型匹配的 catch 块中执行(称作异常被该 catch 块“捕获”),执行完后再跳转到最后一个 catch 块后面继续执行。
1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 double m, n; 6 cin >> m >> n; 7 try { 8 cout << "before dividing." << endl; 9 if (n == 0) 10 throw - 1; //抛出int类型异常 11 else 12 cout << m / n << endl; 13 cout << "after dividing." << endl; 14 } 15 catch (double d) { 16 cout << "catch(double) " << d << endl; 17 } 18 catch (int e) { 19 cout << "catch(int) " << e << endl; 20 } 21 cout << "finished" << endl; 22 return 0; 23 }
程序的运行结果如下:
9 6↙
before dividing.
1.5
after dividing.
finished
说明当 n 不为 0 时,try 块中不会拋出异常。因此程序在 try 块正常执行完后,越过所有的 catch 块继续执行,catch 块一个也不会执行。
程序的运行结果也可能如下:
9 0↙
before dividing.
catch\(int) -1
finished
当 n 为 0 时,try 块中会拋出一个整型异常。拋出异常后,try 块立即停止执行。该整型异常会被类型匹配的第一个 catch 块捕获,即进入catch(int e)
块执行,该 catch 块执行完毕后,程序继续往后执行,直到正常结束。
如果拋出的异常没有被 catch 块捕获,例如,将 catch(int e)
,改为 catch(char e)
,当输入的 n 为 0 时,拋出的整型异常就没有 catch 块能捕获,这个异常也就得不到处理,那么程序就会立即中止,try...catch 后面的内容都不会被执行。
能够捕获任何异常的 catch 语句
catch(...) {
...
}
这样的 catch 块能够捕获任何还没有被捕获的异常。例如下面的程序:
1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 double m, n; 6 cin >> m >> n; 7 try { 8 cout << "before dividing." << endl; 9 if (n == 0) 10 throw - 1; //抛出整型异常 11 else if (m == 0) 12 throw - 1.0; //拋出 double 型异常 13 else 14 cout << m / n << endl; 15 cout << "after dividing." << endl; 16 } 17 catch (double d) { 18 cout << "catch (double)" << d << endl; 19 } 20 catch (...) { 21 cout << "catch (...)" << endl; 22 } 23 cout << "finished" << endl; 24 return 0; 25 }
程序的运行结果如下:
9 0↙
before dividing.
catch (...)
finished
当 n 为 0 时,拋出的整型异常被catchy(...)
捕获。
程序的运行结果也可能如下:
0 6↙
before dividing.
catch (double) -1
finished
当 m 为 0 时,拋出一个 double 类型的异常。虽然catch (double)
和catch(...)
都能匹配该异常,但是catch(double)
是第一个能匹配的 catch 块,因此会执行它,而不会执行catch(...)
块。由于catch(...)
能匹配任何类型的异常,它后面的 catch 块实际上就不起作用,因此不要将它写在其他 catch 块前面。
引用自:https://www.cnblogs.com/yx12789/p/16821814.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)