[C++] 异常处理机制及使用案例

什么是C++异常处理?

C++ 异常处理是一种机制,用于在程序运行过程中处理可能发生的错误或异常情况。当发生异常时,程序会跳出当前的执行流程,并查找能够处理该异常的代码块,执行相应的处理逻辑,从而避免程序崩溃或产生未定义行为。

异常可以是由系统抛出的(如内存分配失败)或由程序员主动抛出的(如检测到输入错误)。C++ 中的异常处理机制主要包括以下几个部分:

  1. 异常的抛出:使用 throw 关键字抛出异常对象。

  2. 异常的捕获:使用 try-catch 块捕获异常,并执行相应的处理逻辑。

  3. 异常的处理:在 catch 块中,可以对捕获到的异常进行处理,包括输出异常信息、记录日志、重新抛出异常或返回默认值等。

  4. 异常的传递:如果异常没有被捕获,它会在调用栈中继续向上抛出,直到遇到能够处理异常的代码块。

异常处理能够增强程序的健壮性和可靠性,使得程序能够更好地应对异常情况并进行相应的处理。

C++ 异常处理的案例

以下是一些使用 C++ 异常处理的案例:

数组越界异常处理

#include <iostream>
#include <stdexcept>

int main() {
    int arr[3] = {1, 2, 3};
    try {
        int val = arr[5];
    } catch(const std::out_of_range& e) {
        std::cout << "数组越界异常:" << e.what() << std::endl;
    }
    return 0;
}

文件打开异常处理

#include <iostream>
#include <fstream>
#include <stdexcept>

int main() {
    std::ifstream file;
    try {
        file.open("nonexistent.txt");
        if (!file.is_open()) {
            throw std::runtime_error("文件打开失败");
        }
        // 其他文件操作
        file.close();
    } catch(const std::exception& e) {
        std::cout << "异常:" << e.what() << std::endl;
    }
    return 0;
}

自定义异常类

#include <iostream>
#include <stdexcept>

class MyException : public std::exception {
public:
    MyException(const char* message) : m_message(message) {}
    virtual const char* what() const noexcept {
        return m_message;
    }
private:
    const char* m_message;
};

int divide(int numerator, int denominator) {
    if (denominator == 0) {
        throw MyException("除数不能为零");
    }
    return numerator / denominator;
}

int main() {
    try {
        int result = divide(10, 0);
    } catch(const MyException& e) {
        std::cout << "自定义异常:" << e.what() << std::endl;
    }
    return 0;
}

这些示例展示了如何使用 C++ 异常处理来处理各种异常情况,保护代码免受错误的影响,并提供适当的错误信息。

stdexcept 标准库

stdexcept 是 C++ 标准库中的头文件,其中定义了一些常见的异常类。它提供了一组用于常见异常类型的类,这些异常类是从 std::exception 类派生而来的。

以下是 stdexcept 头文件中定义的异常类和使用案例:

std::logic_error 异常类

  • std::logic_error 是一个基类,用于派生针对逻辑错误的异常类,如 std::invalid_argument 和 std::length_error

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int main() {
        try {
            throw std::logic_error("逻辑错误");
        } catch(const std::logic_error& e) {
            std::cout << "逻辑错误异常:" << e.what() << std::endl;
        }
        return 0;
    }
    
    

std::invalid_argument 异常类

  • std::invalid_argument 表示传递给函数的参数无效。

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int divide(int numerator, int denominator) {
        if (denominator == 0) {
            throw std::invalid_argument("除数不能为零");
        }
        return numerator / denominator;
    }
    
    int main() {
        try {
            int result = divide(10, 0);
        } catch(const std::invalid_argument& e) {
            std::cout << "无效参数异常:" << e.what() << std::endl;
        }
        return 0;
    }

std::length_error 异常类

  • std::length_error 表示长度错误,例如字符串长度超出限制。

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int main() {
        try {
            std::string str(1000000000, 'a');  // 创建一个长度为 1,000,000,000 的字符串
        } catch(const std::length_error& e) {
            std::cout << "长度错误异常:" << e.what() << std::endl;
        }
        return 0;
    }

std::out_of_range 异常类

  • std::out_of_range 表示索引超出范围,例如数组越界或迭代器越界。

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int main() {
        try {
            std::vector<int> vec = {1, 2, 3};
            int value = vec.at(5);  // 索引超出范围
        } catch(const std::out_of_range& e) {
            std::cout << "索引超出范围异常:" << e.what() << std::endl;
        }
        return 0;
    }

通过使用 stdexcept 中定义的异常类,可以更方便地创建和处理常见的异常情况,提供有用的错误信息,并帮助代码更健壮地处理异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/408882.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux进程【补充】

文章目录 进程概念task_struct 进程创建forkvfork写时拷贝 进程状态僵尸进程孤儿进程守护进程 进程地址空间是什么为什么怎么做 进程概念 进程是一个程序的执行实例或者是担当系统资源分配的实体。当一个程序运行时&#xff0c;被从硬盘加载到内存中&#xff0c;操作系统为每个…

python 线程笔记一 (概念+示例代码)

1. 线程的概念 线程&#xff0c;可简单理解为是程序执行的一条分支&#xff0c;也是程序执行流的最小单元。线程是被系统独立调度和分派的基本单位&#xff0c;线程自己不拥有系统资源&#xff0c;只拥有一点儿在运行中必不可少的资源&#xff0c;但它可与同属于一个进程的其它…

第10届蓝桥杯Scratch图形化编程 选拔赛初级组编程题1:小猫走城堡

准备工作: 导入育最库中的“Castle 3 小猫从坐标点(-165&#xff0c;-93)出发向城堡走去。随着位置的移动&#xff0c;角色大小逐渐变小&#xff0c;最后在城堡前消失。注意1.角色大小在逐渐变化&#xff0c;运行结束再次点击绿旗&#xff0c;程序应还能再次扶行。2.角色应该是…

云原生之API网关Traefik

1. 前言 说到web服务的开源网关&#xff0c;我首先想到的是Nginx&#xff0c;最早使用的就是它&#xff0c;现在都还在使用它。系统上线了Docker Swarm集群之后&#xff0c;不继续使用Nginx直接做Docker服务的网关&#xff0c;是因为Nginx毕竟比Docker Swarm出现的早&#xff0…

YOLOv7基础 | 第2种方式:简化网络结构之yolov7.yaml(由104层简化为30层)

前言:Hello大家好,我是小哥谈。通过下载YOLOv7源码可知,原始的yolov7.yaml文件是拆开写的,比较混乱,也不好理解,并且为后续改进增添了很多困难。基于此种情况,笔者就给大家介绍一种将yolov7.yaml文件简化的方法,将104层简化为30层,并且参数量和计算量和原来是一致的,…

✅鉴权—cookie、session、token、jwt、单点登录

基于 HTTP 的前端鉴权背景cookie 为什么是最方便的存储方案&#xff0c;有哪些操作 cookie 的方式session 方案是如何实现的&#xff0c;存在哪些问题token 是如何实现的&#xff0c;如何进行编码和防篡改&#xff1f;jwt 是做什么的&#xff1f;refresh token 的实现和意义ses…

pythonJax小记(五):python: 使用Jax深度图像(正交投影和透视投影之间的转换)(持续更新,评论区可以补充)

python: 使用Jax深度图像&#xff08;正交投影和透视投影之间的转换&#xff09; 前言问题描述1. 透视投影2. 正交投影 直接上代码解释1. compute_projection_parameters 函数a. 参数解释b. 函数计算 2. ortho_to_persp 函数a. 计算投影参数&#xff1a;b. 生成像素坐标网格&am…

protobuf简单使用(二)

介绍 上一节中&#xff0c;我们介绍了protobuf&#xff0c;简单来说&#xff0c;它是一种消息数据格式&#xff0c;其作用类似于json&#xff0c;但是比json的使用效率要高。 除此以外&#xff0c;我们介绍了protobuf的简单使用&#xff0c;也就是如何可以像使用json一样&…

AI游戏初创公司“奇酷网络”,获得500万元天使投资

发布 | 大力财经 2024年新春伊始的2月25日&#xff0c;国内首家“AI游戏”应用公司“奇酷网络”正式对外宣布&#xff1a;以3,000万元人民币的估值&#xff0c;成功获得500万元人民币的融资&#xff1b;资金来源于一名百度高层和一位知名的天使投资人。 据悉&#xff0c;“奇…

进程 2月24日学习笔记

1.进程: 程序&#xff1a;存放在外存中的一段数据组成的文件 进程&#xff1a;是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡 2.进程相关命令: 1.top 动态查看当前系统中的所有进程信息&#xff08;根据CPU占用率排序&#xff09; PID:唯一识…

namecheap域名如何购买?通过支付宝(详细图文教程)

引言 在完成博客搭建的时候&#xff0c;我们可能需要一个好的域名&#xff0c;自己看起来才会舒服点&#xff0c;同时也可以通过google或者百度等方式搜索到自己博客。 经过实验发现&#xff0c;一个好的后缀名会增强google和百度的搜索seo&#xff0c;增加自己博客的流量。 …

平头哥IP核C906的JTAG调试器DIY教程(一)

背景 最近买了一块基于平头哥C906核&#xff0c;SOC为全志的D1s&#xff0c;的核心板&#xff0c;手工焊接在白嫖的底板上&#xff08;此处感谢百问网老师的友情支持&#xff0c;手动狗头&#xff09;。在焊接完成后&#xff0c;进行点亮跑程序的时候&#xff0c;发现没有优雅…

C++ //练习 8.13 重写本节的电话号码程序,从一个命名文件而非cin读取数据。

C Primer&#xff08;第5版&#xff09; 练习 8.13 练习 8.13 重写本节的电话号码程序&#xff0c;从一个命名文件而非cin读取数据。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /***************************************…

关于设备连接有人云的使用及modbus rtu协议,服务器端TCP调试设置

有人云调试 调试过程问题1. 关于modbus rtu协议,实质上有三种modbus基本原理modbus 格式2. 关于modbus crc16通信校验3. 关于在ubuntu阿里云服务器端,监听网络数据之调试mNetAssist4. 使用有人FAE传给的设置软件问题???之前的一个项目,再拿出来回顾下。 调试过程 先 要在有…

web安全学习笔记【16】——信息打点(6)

信息打点-语言框架&开发组件&FastJson&Shiro&Log4j&SpringBoot等[1] #知识点&#xff1a; 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-C…

特征选择|一种提升预测模型性能的方法(原理及其优化实现,Matlab)

文章来源于我的个人公众号&#xff1a;KAU的云实验台&#xff0c;主要更新智能优化算法的原理、应用、改进 如今&#xff0c;生成的数据集呈指数级增长&#xff0c;这将产生具有大量特征和样本的数据集&#xff0c;而显然&#xff0c;某些特征是不相关/冗余的&#xff0c;它们…

奇异递归模板模式应用6-类模板enable_shared_from_this

异步编程中存在一种场景&#xff0c;需要在类中将该类的对象注册到某个回调类或函数中&#xff0c;不能简单地将this传递给回调类中&#xff0c;很可能因为回调时该对象不存在而导致野指针访问&#xff08;也有可能在析构函数解注册时被回调&#xff0c;造成对象不完整&#xf…

【C语言基础】:操作符详解(一)

文章目录 操作符详解1. 操作符的分类2. 二进制和进制转换2.1 什么是二进制、八进制、十进制、十六进制2.1.1 二进制和进制转换2.1.2 二进制转十进制2.2.3 二进制转八进制2.2.4 二进制转十六进制 3. 源码、反码、补码4. 移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&…

IT廉连看——C语言——函数

IT廉连看——C语言——函数 一、函数是什么&#xff1f; 数学中我们常见到函数的概念。但是你了解C语言中的函数吗&#xff1f; 维基百科中对函数的定义&#xff1a;子程序 在计算机科学中&#xff0c;子程序&#xff08;英语&#xff1a;Subroutine, procedure, function, …

【Java】java异常处理机制(实验五)

目录 一、实验目的 二、实验内容 三、实验小结 一、实验目的 1、理解java的异常处理机制 2、掌握try catch结构和thow和thows关键字的用法 二、实验内容 1、编写一个程序&#xff0c;输入某个班某门课程成绩&#xff0c;统计及格人数、不及格人数及课程平均分。设计一个异…