C++进阶-异常处理
2021/4/15 12:25:11
本文主要是介绍C++进阶-异常处理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
异常处理
异常处理使用try
关键字来尝试执行可能会出现异常的代码段,当在代码段的执行过程中有异常发生时,系统会抛出相应类型的异常,由紧随其后的catch
关键字对异常进行捕获,并交由相应类型的异常处理分支对其进行恰当的处理,比如结束正在执行的操作、清理不再需要的资源等,从而尽可能地挽回用户的损失。
// 用 try 开始异常处理语句 try { // 包含可能发生异常的语句 } catch(异常类型 [形参名]) // 捕获特定类型的异常 { // 对此类型异常进行处理 } catch(异常类型 [形参名]) // 捕获特定类型的异常 { // 对此类型异常进行处理 } // 可以有多个 catch 语句并列,捕获不同类型的异常 catch(...) // 如果省略具体的异常类型用“...”表示,则表示捕获所有类型的异常 { // 对所有类型的异常进行处理 }
使用throw
关键字抛出一个相应类型的异常,表示某种异常情况的发生,需要后面的 catch 语句捕获并对其进行处理。用 throw 关键字抛出一个异常的语法格式如下:
throw 异常表达式;
异常表达式就是要抛出的异常,它可以是表示异常类型的错误代码,或者是含有异常相关信息的某个对象,总之,它的意义是为异常处理提供相应的辅助信息。
// 除法函数 double Divide( int a, int b ) { if( 0 == b ) throw "不能使用 0 作为除数"; return (double)a/b; }
当 throw关键字抛出的异常被某个 catch 语句捕获时, throw 关键字后的异常表达式会被当成实际参数传递给catch 语句中的形式参数,进而 catch 语句可以根据这个参数提供的信息对异常进行具体的处理。当有多种类型的异常需要捕获时,可以将多个 catch 语句并列。如果省略 catch 关键字后面的形式参数而使用“…”代替,则表示 catch 语句会捕获所有类型的异常。
// 开始异常处理语句 try { cout<<"请输入被除数与除数: "<<endl; int a,b; // 被除数与除数 cin>>a>>b; // 接收用户输入 // 进行除法运算,当 b 为 0 时会抛出异常 double fRes = Divide( a, b ); cout<<a<<"/"<<b<<" = "<<fRes<<endl; // 输出结果 } // 捕获 try 语句块中所抛出的字符串类型异常 catch( char* pMsg ) { // 对异常进行处理 // 这里仅仅是输出错误信息 cout<<"程序运行发生异常: "<<pMsg<<endl; }
在函数声明之后用 throw 关键字加一个括号,括号中列出这个函数可能抛出的异常类型,如果有多个类型的异常,可以用逗号间隔。
例如, Divide()函数可能会抛出字符串类型和浮点数类型的类型,则可以将其定义如下:
// 可能抛出 char*和 double 类型的异常 double Divide( int a, int b ) throw ( const char*, double ) { // … }
如果在函数的声明中没有包括异常的接口声明,则此函数可以抛出任何类型的异常。例如:
// 可以抛出任何类型的异常 double Divide( int a, int b );
相反,如果一个函数不会抛出异常,那么我们可以将函数声明中 throw 关键字之后的异常类型列表留空,或者是用 noexcept 关键字对函数进行修饰,表示这个函数不会抛出任何类型的异常,函数的使用者无需将其放到 try 语句块中来执行。例如:
// 不会抛出任何类型的异常 double Divide( int a, int b ) throw();double sqrt(double a) noexcept;
如果一个经过 noexcept 修饰的函数确实在执行的时候抛出了异常,那么程序会通过调用
terminate()函数来结束自己的执行。这样做可能会留下很多后遗症,例如,它无法保证对象的析构函数的正常调用,也无法保证栈的自动释放等。但是,在可以预见异常极少发生的情况下,将函数用 noexcept 修饰却是一种简单而直接,却非常有效的异常处理机制,它可以简化异常处理从而在一定程度上提高程序的执行效率。
这篇关于C++进阶-异常处理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升