当前位置: 首页 > news >正文

C++学习---异常处理机制

文章目录

  • 前言
  • abort()函数 and 返回错误码的异常方式
  • C++异常处理机制
    • 异常的类别
      • what()函数

前言


abort()函数 and 返回错误码的异常方式

在说C++异常处理机制之前,了解一下abort()函数和返回错误码的异常处理。

Abort( )函数的原型位于头文件cstdlib(或stdlib.h)中,其典型实现是向标准错误流(即cerr使用的错误流)发送消息abnormal program termination(程序异常终止),然后终止程序。

其部分实现代码:

在这里插入图片描述

运行程序后,输入 10 和 -10 会返回错误信息,“”

在这里插入图片描述

注意使用abort()函数的话是直接终止程序,而不是返回main()函数。

比abort()函数更灵活的办法是使用返回错误码的形式来指出异常问题。

可使用指针参数引用参数来将值返回给调用程序,并使用函数的返回值来指出成功还是失败。

实例:

#include <iostream>
#include <cfloat>bool hmean(double a, double b, double *ans);int main()
{double x, y, z;std::cout << "Enter two numbers: ";while (std::cin >> x >> y){if (hmean(x, y, &z))std::cout << "Harmonic mean of " << x << " and " << y<< " is " << z << std::endl;else   std::cout << "One value should not be the negative "<< "of the other - try again.\n";std::cout << "Enter next set of numbers <q to quit>: ";}std::cout << "Bye!\n";return 0;
}bool hmean(double a, double b, double *ans)
{if (a == -b){*ans = DBL_MAX;return false;}else{*ans = 2.0 * a * b / (a + b);return true;}
}

运行结果:

在这里插入图片描述


C++异常处理机制

C++提供了一种异常处理机制,允许程序在运行时出现错误时抛出异常,并在适当的位置捕获和处理这些异常。

C++的异常处理通常会涉及到三个关键字:throwtrycatch

  • throw:异常抛出,当程序发生错误或异常情况时,可以使用 throw 语句来抛出异常;异常可以是标准类型(如整数或字符串)或自定义类型。
throw SomeException("An error occurred");
  • try、catch:异常捕获,在 try 块中放置可能引发异常的代码,然后在一个或多个 catch 中捕获并处理异常,每个 catch 块可以捕获不同种类的异常。
try {// 可能引发异常的代码
} catch (SomeException& ex) {// 处理 SomeException 异常
} catch (AnotherException& ex) {// 处理 AnotherException 异常
}

一个示例:

#include <iostream>
double hmean(double a, double b);int main()
{double x, y, z;std::cout << "Enter two numbers: ";while (std::cin >> x >> y){try {z = hmean(x, y);}catch (const char *s){std::cout << s << std::endl;std::cout << "Enter a new pair of numbers: ";continue;}std::cout << "Harmonic mean of " << x << " and " << y<< " is " << z << std::endl;std::cout << "Enter next set of numbers <q to quit>: ";}std::cout << "Bye!\n";return 0;
}double hmean(double a, double b)
{if (a == -b)throw "bad hmean() arguments: a = -b not allowed";return 2.0 * a * b / (a + b);
}

运行结果:

在这里插入图片描述

上述程序中,try块中是可能引发异常的代码,catch块中是对异常的处理。

执行throw语句类似于执行返回语句,因为它也将终止函数的执行;但throw不是将控制权返回给调用程序,而是导致程序沿函数调用序列后退,直到找到包含try块的函数。

接下来看将10和−10传递给hmean( )函数后发生的情况。
If语句导致hmean( )引发异常。这将终止hmean( )的执行。程序向后搜索时发现,hmean( )函数是从main( )中的try块中调用的,因此程序查找与异常类型匹配的catch块。程序中唯一的一个catch块的参数为char*,因此它与引发异常匹配。程序将字符串“bad hmean( )arguments: a = -b not allowed”赋给变量s,然后执行处理程序中的代码。处理程序首先打印s——捕获的异常,然后打印要求用户输入新数据的指示,最后执行continue语句,命令程序跳过while循环的剩余部分,跳到起始位置。

在这里插入图片描述

如果 没有触发异常,就不会进入catch块,程序回执行catch后的第一条语句。如上面实例输入 1和2后的结果。


异常的类别

throw关键字用于抛出一个异常,通常是在检测到错误或异常情况时,你可以抛出任何类型的数据,通常是一个对象,但也可以是基本数据类型,如整数。

如:

if (condition) {throw MyException("Something went wrong");}

在上述中,如果condition满足的话,就会抛出一个自定义异常**MyException**,然后在catch块中捕获异常。

在执行 throw 语句时,throw 表达式的值会被复制构造为一个新的异常对象。这个异常对象包含有关异常的信息,例如类型和其他相关数据。

异常的类别:异常可以分为不同的类别,这些类别通常是派生自 std::exception 类的自定义异常类,但也可以使用内置的异常类,如 int(整数异常)。

在C++中提供了一系列标准的异常,定义在 中,我们可以在程序中使用这些标准的异常。它们是以父子类层次结构组织起来的,如下所示:
在这里插入图片描述

下表是对上面层次结构中出现的每个异常的说明:
在这里插入图片描述

一个使用了std::logic_error类别的示例:

#include <iostream>
#include <stdexcept>int divide(int numerator, int denominator) {if (denominator == 0) {throw std::logic_error("Division by zero is not allowed");}return numerator / denominator;
}int main() {try {int result = divide(10, 2);std::cout << "Result: " << result << std::endl;result = divide(10, 0); // 引发逻辑错误异常std::cout << "Result: " << result << std::endl; // 这一行不会执行} catch (const std::logic_error& ex) {std::cerr << "Logic error caught: " << ex.what() << std::endl;}return 0;
}

输出结果:
在这里插入图片描述

除了使用C++提供的异常类别外,我们也可以自定义异常,例如throw中的MyException;

我们可以定义一个名为MyException的自定义异常类,它继承自std::exception

class MyException : public std::exception {
public:MyException(const char* message) : message_(message) {}const char* what() const noexcept override {return message_.c_str();}private:std::string message_;
};

在上述代码中,public中 有个构造函数MyException, const char* message表示接收一个字符串指针,存放到后面的message_成员变量中。
接着重写了 what()函数,它返回一个指向异常消息的const char*指针。what()函数被标记为const noexcept override,表示它是一个虚函数,不会引发异常,而且是不可更改的。

完整代码如下:

#include <iostream>
#include <stdexcept>class MyException : public std::exception {
public:MyException(const char* message) : message_(message) {}const char* what() const noexcept override {return message_.c_str();}private:std::string message_;
};int divide(int numerator, int denominator) {if (denominator == 0) {throw MyException("Custom Exception: Division by zero is not allowed");}return numerator / denominator;
}int main() {try {int result = divide(10, 2);std::cout << "Result: " << result << std::endl;result = divide(10, 0); // 引发自定义异常std::cout << "Result: " << result << std::endl; // 这一行不会执行} catch (const MyException& ex) {std::cerr << "Custom Exception caught: " << ex.what() << std::endl;}return 0;
}

what()函数

关于what()函数:

what()函数是C++中异常类的一个成员函数,用于返回一个描述异常的人类可读的错误消息。通常,在自定义异常类中,你可以重写what()函数以提供有关异常的详细信息。在标准的std::exception类及其派生类中,what()函数已经被实现,以返回一个默认的错误消息。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • BI数据可视化:不要重复做报表,只需更新数据
  • JSP通用材料收集归档系统eclipse定制开发mysql数据库BS模式java编程jdbc
  • 结合DevOps实践:使用Huawei CodeArts和CCE进行自动化Kubernetes集群部署
  • 3. List
  • 微服务之Eureka
  • 集简云平台助力无代码开发,实现平安银行与电商平台、CRM系统的快速连接
  • 每日汇评:黄金正在期待鲍威尔的讲话以获取新的方向动力
  • Linux 内核中根据文件inode号获取其对应的struct inode
  • 【计算机网络实验/wireshark】tcp建立和释放
  • PTA 哈利·波特的考试(floyd算法)
  • 【沐风老师】3dMax快速平铺纹理插件QuickTiles教程
  • 手握“发展密钥”,TCL科技或迎价值重估?
  • 【MongoDB-Redis-MySQL-Elasticsearch-Kibana-RabbitMQ-MinIO】Java全栈开发软件一网打尽
  • 用java代码实现security
  • 使用Scrapy的调试工具和日志系统定位并解决爬虫问题
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • centos安装java运行环境jdk+tomcat
  • conda常用的命令
  • Cumulo 的 ClojureScript 模块已经成型
  • github从入门到放弃(1)
  • laravel5.5 视图共享数据
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • spring + angular 实现导出excel
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • Vue全家桶实现一个Web App
  • zookeeper系列(七)实战分布式命名服务
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 高程读书笔记 第六章 面向对象程序设计
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 经典排序算法及其 Java 实现
  • 聊一聊前端的监控
  • 三分钟教你同步 Visual Studio Code 设置
  • 实现简单的正则表达式引擎
  • 使用agvtool更改app version/build
  • 小李飞刀:SQL题目刷起来!
  • 新手搭建网站的主要流程
  • 移动端解决方案学习记录
  • 再次简单明了总结flex布局,一看就懂...
  • 正则表达式小结
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (20050108)又读《平凡的世界》
  • (二)构建dubbo分布式平台-平台功能导图
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)jQuery 基础
  • (转)ObjectiveC 深浅拷贝学习
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET CORE 3.1 集成JWT鉴权和授权2