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

「C++系列」异常处理

【人工智能教程】,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。

点击跳转到网站:【人工智能教程】
在这里插入图片描述

文章目录

  • 一、异常处理
    • 1. 基本概念
    • 2. 示例代码
    • 3. 注意事项
  • 二、常见的异常类
    • 1. 继承自`std::exception`的基类
    • 2. 逻辑错误(`std::logic_error`派生)
    • 3. 运行时错误(`std::runtime_error`派生)
    • 4. 特定于内存和类型转换的异常
    • 5. 自定义异常类
    • 6. 使用异常类的示例
  • 三、相关链接

一、异常处理

C++ 异常处理是一种错误处理机制,它允许程序在运行时检测和处理错误情况。这种机制通过使用 trycatchthrow 关键字来实现。当函数遇到无法处理的错误时,它会抛出一个异常(通过 throw 关键字),这个异常可以被调用者捕获并处理(通过 catch 块)。如果没有被捕获,异常会传播到更高层的调用者,直到被捕获或导致程序终止。

1. 基本概念

  • throw:用于抛出一个异常。它可以抛出 C++ 中的任何类型,但通常是抛出一个从标准异常类派生的对象。
  • try:用于指定代码块,当块内发生异常时,程序的控制流会跳转到与之关联的 catch 块。
  • catch:用于捕获并处理异常。catch 块可以紧跟在 try 块之后,并且可以有多个 catch 块来捕获不同类型的异常。

2. 示例代码

#include <iostream>
#include <stdexcept> // 包含标准异常类void func() {// 假设这里发生了一个错误throw std::runtime_error("发生了一个运行时错误!");
}int main() {try {func(); // 调用func,它可能会抛出一个异常} catch (const std::runtime_error& e) {// 捕获到runtime_error异常std::cerr << "捕获到异常: " << e.what() << std::endl;} catch (...) {// 捕获所有其他类型的异常std::cerr << "捕获到未知异常" << std::endl;}return 0;
}

3. 注意事项

  1. 异常规格:在 C++11 之前,函数可以声明它可以抛出的异常类型(异常规格)。但从 C++11 开始,非抛出异常规格(throw())被废弃,并且在 C++17 中被完全移除。现代 C++ 代码通常不再使用异常规格。
  2. 资源泄露:在使用异常处理时,要特别注意资源管理,防止资源泄露。一种常见的方法是使用 RAII(Resource Acquisition Is Initialization)技术,通过智能指针(如 std::unique_ptrstd::shared_ptr)来自动管理资源。
  3. 异常层次结构:在设计自定义异常时,应该继承自标准异常类(如 std::exception),这有助于维护清晰的异常层次结构,并允许调用者更容易地处理异常。
  4. 避免在析构函数中抛出异常:在析构函数中抛出异常可能会导致程序崩溃,因为析构函数是在处理异常的过程中被调用的。如果析构函数需要处理错误情况,它应该采用其他错误处理机制(如记录错误日志或设置错误状态码)。
  5. 性能考虑:虽然异常处理提供了强大的错误处理机制,但它可能会对性能产生负面影响。因此,在性能敏感的代码区域中,应该谨慎使用异常处理,并考虑使用其他错误处理机制(如错误码和错误状态)。

二、常见的异常类

C++中常见的异常类主要包括标准异常类和自定义异常类。标准异常类是由C++标准库提供的,用于表示各种常见的错误情况。以下是一些常见的标准异常类:

1. 继承自std::exception的基类

  • std::exception:所有标准异常的基类,提供了基本的异常接口,包括what()函数,该函数返回一个表示异常的字符串指针。

2. 逻辑错误(std::logic_error派生)

逻辑错误是在程序运行前可以检测出来的错误,它们通常是由于程序内部的逻辑问题导致的。

  • std::domain_error:当函数的参数值不在其允许的有效范围内时抛出。
  • std::invalid_argument:指出函数的一个无效参数。
  • std::length_error:当尝试生成一个超出该类型最大长度的对象时抛出。
  • std::out_of_range:当使用一个超出有效范围的值时抛出,如在数组或字符串中采用了一个错误的索引。

3. 运行时错误(std::runtime_error派生)

运行时错误是在程序运行过程中才能检测到的错误。

  • std::range_error:当内部计算时发生区间错误时抛出。
  • std::overflow_error:当算术运算结果超出可表示的最大值时抛出。
  • std::underflow_error:当算术运算结果超出可表示的最小值时抛出。

4. 特定于内存和类型转换的异常

  • std::bad_alloc:当new操作无法分配足够的内存时抛出。
  • std::bad_cast:在运行时类型识别中有一个无效的dynamic_cast表达式时抛出。
  • std::bad_typeid:当对空指针使用typeid操作时抛出。

5. 自定义异常类

除了上述标准异常类外,程序员还可以根据需要创建自定义异常类。自定义异常类通常通过继承自std::exception或某个更具体的标准异常类来实现,以便提供额外的错误信息或特定的行为。

6. 使用异常类的示例

#include <iostream>
#include <stdexcept>int main() {try {// 假设这里有一段可能抛出异常的代码if (/* 某种错误条件 */) {throw std::invalid_argument("无效的参数");}} catch (const std::invalid_argument& e) {std::cerr << "捕获到异常: " << e.what() << std::endl;} catch (...) {std::cerr << "捕获到未知异常" << std::endl;}return 0;
}

在编写C++程序时,合理使用异常处理机制可以提高程序的健壮性和可维护性。通过抛出和捕获异常,程序可以在遇到错误时优雅地处理,而不是突然崩溃或产生未定义的行为。
在这里插入图片描述

三、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型
  6. 「C++系列」C++ 变量类型
  7. 「C++系列」C++ 变量作用域
  8. 「C++系列」C++ 常量知识点-细致讲解
  9. 「C++系列」C++ 修饰符类型
  10. 「C++系列」一篇文章说透【存储类】
  11. 「C++系列」一篇文章讲透【运算符】
  12. 「C++系列」循环
  13. 「C++系列」判断
  14. 「C++系列」函数/内置函数
  15. 「C++系列」数字/随机数
  16. 「C++系列」数组
  17. 「C++系列」字符串
  18. 「C++系列」指针
  19. 「C++系列」引用
  20. 「C++系列」日期/时间
  21. 「C++系列」输入/输出
  22. 「C++系列」数据结构
  23. 「C++系列」vector 容器
  24. 「C++系列」类/对象
  25. 「C++系列」继承
  26. 「C++系列」重载运算符/重载函数
  27. 「C++系列」多态
  28. 「C++系列」数据抽象
  29. 「C++系列」数据封装
  30. 「C++系列」 接口(抽象类)
  31. 「C++系列」文件和流

http://www.mrgr.cn/news/29857.html

相关文章:

  • 速盾:凡科建站开cdn了吗?
  • 【从计算机的发展角度理解编程语言】C、CPP、Java、Python,是偶然还是应时代的产物?
  • 硬件开篇——体系架构
  • 408算法题leetcode--第八天
  • [Redis][Redis简介]详细讲解
  • 【无标题】Java_Se 数据变量与运算符
  • Linux C高级 day1
  • 7.7opencv中(基于C++) 翻转图像
  • Linux运维篇-服务器简介
  • 微博计算架构实战
  • Linux进阶 查看系统进程
  • 【漏洞复现】Nacos Derby SQL注入漏洞
  • Java中的语法糖:让编程更简洁的特性
  • 15. 三数之和(左右指针)
  • 【protobuf】ProtoBuf的学习与使用⸺C++
  • Springboot多种请求参数
  • 单细胞BCR的分析Dandelion重注释的安装以及用法----11111
  • java高频面试题(2024最新)
  • MySQL高阶1831-每天的最大交易
  • 视频转文字工具:开启视频内容深度挖掘的钥匙