「C++系列」异常处理

news/2024/9/19 8:16:00 标签: c++, 开发语言, 算法, c语言, java

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

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

文章目录

  • 一、异常处理
    • 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.niftyadmin.cn/n/5665240.html

相关文章

汽车软件开发之敏捷开发

一、前言 目前汽车电子产品&#xff0c;特别是汽车几大域控&#xff08;如&#xff1a;智能座舱、智能驾驶、智能网联、车身控制&#xff09;市场竞争激烈&#xff0c;消费者对汽车的需求逐渐多元化和个性化&#xff0c;用户对座舱和智驾产品的要求也越来越高。他们不仅要求产…

react + antDesignPro 企业微信扫码登录

效果 实现步骤 1、项目中document.ejs文件引入企微js链接 注意&#xff1a;技术栈是使用的react antDesignPro&#xff0c;不同的技术栈有不同的入口文件&#xff08;如vue在html文件引入&#xff09; <script src"https://wwcdn.weixin.qq.com/node/wework/wwopen/j…

11 - TCPClient实验

在上一个章节的UDP通信测试中&#xff0c;尽管通信的实现过程相对简洁&#xff0c;但出现了通信数据丢包的问题。因此&#xff0c;本章节将基于之前建立的WIFI网络连接&#xff0c;构建一个基础的TCPClient连接机制。我们利用网络调试助手工具来发送数据&#xff0c;测试网络通…

使用Maven创建一个Java项目并在repository中使用

JDK环境&#xff1a;1.8.0_371 Maven环境 &#xff1a;Apache Maven 3.6.3 配置完成jdk和mvn后&#xff0c;进入到指定文件夹下执行如下语句&#xff1a; mvn archetype:generate -DgroupIdtop.chengrongyu -DartifactIdCyberSpace -DarchetypeArtifactIdmaven-archetype-quic…

接口幂等性和并发安全的区别?

目录标题 幂等性并发安全总结 接口幂等性和并发安全是两个不同的概念&#xff0c;虽然它们在设计API时都很重要&#xff0c;但侧重点不同。 幂等性 定义&#xff1a;幂等性指的是无论对接口进行多少次相同的操作&#xff0c;结果都是一致的。例如&#xff0c;HTTP的PUT和DELE…

ts类型谓词和never

ts谓词 有时会写一些用于判断变量类型的工具函数&#xff0c;然后根据函数返回的布尔值来做逻辑处理。比如下面的代码例子&#xff1a; function isArrayBoolean(value: unknown): boolean {return Array.isArray(value); }if (isArrayBoolean(value)) {// TypeScript 仍然认…

暑假考研集训营游记

文章目录 摘要&#xff1a;1.对各大辅导机构考研封闭集训营的一些个人看法&#xff1a;2.对于考研原因一些感想&#xff1a;结语 摘要&#xff1a; Ashy在暑假的时候参加了所在辅导班的为期一个月的考研封闭集训营&#xff0c;有了一些全新的感悟&#xff0c;略作记录。 1.对…

Vue 3 是 Vue.js 的下一代版本,它在许多方面都带来了显著的改进和变化,旨在提高开发效率和用户体验

性能提升&#xff1a; Vue 3 引入了一个新的编译系统&#xff08;Proxy-based&#xff09;和响应式系统&#xff08;Proxy&#xff09;&#xff0c;这极大地提高了性能。Proxy 相比 Vue 2 中的 Object.defineProperty&#xff0c;在处理嵌套对象和数组时更加高效和灵活。静态提…