C++异常处理 throw try catch

news2025/4/6 9:09:35

C++ 异常处理概述

C++ 异常处理机制提供了一种在程序运行时捕获错误或异常情况的方式。异常处理的目的是使得程序在遇到错误时能够优雅地终止或恢复,并防止程序出现崩溃。C++ 使用 try, throw, 和 catch 关键字来实现异常处理。

异常处理的基本结构:

  1. throw: 用来抛出异常,可以是任意类型的对象。

  2. try: 用来包裹可能抛出异常的代码块。

  3. catch: 用来捕获特定的异常类型并处理。

1. throw 关键字

throw 用于抛出异常。当程序执行到 throw 时,会跳出当前的代码块,异常被抛出,程序开始寻找相应的 catch 语句。

  • 语法throw expression;

    • expression 可以是任何数据类型,通常是一个异常对象。

    • 可以抛出内建类型、类对象、指针等。

throw 42;  // 抛出整数 42
throw std::runtime_error("An error occurred");  // 抛出异常对象

2. try

try 块是包含可能会抛出异常的代码的区域。当 try 块中的代码抛出异常时,控制权会跳转到相应的 catch 块中。

  • 语法

    try {
        // 可能抛出异常的代码
    }
    

3. catch

catch 用于捕获异常,并且可以处理它。catch 块的形式取决于抛出的异常类型。如果异常类型匹配,catch 语句就会捕获它。

  • 语法

    catch (ExceptionType e) {
        // 处理异常
    }
    
    • 你可以捕获特定的异常类型,也可以使用通用的 catch(...) 来捕获任何类型的异常。

基本的异常处理示例:

#include <iostream>
#include <stdexcept>  // std::runtime_error

void testFunction() {
    throw std::runtime_error("An error occurred");
}

int main() {
    try {
        testFunction();  // 可能抛出异常的函数
    }
    catch (const std::exception& e) {  // 捕获异常
        std::cout << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}

详细讲解:

1. 抛出异常

try 块中,可能会发生错误。此时,你可以使用 throw 语句来抛出异常对象。你可以抛出任何类型的对象,常见的类型包括:

  • 基本数据类型(如 int, double

  • 类或结构体对象

  • 标准库异常类(如 std::exception, std::runtime_error

例子:

throw std::out_of_range("Index out of range");  // 抛出标准异常对象

2. 捕获异常

catch 块会根据其类型匹配捕获不同的异常对象。你可以为不同的异常类型设置多个 catch 块。异常处理机制是基于异常类型进行匹配的,匹配成功的 catch 块会执行。

try {
    // 代码可能抛出不同类型的异常
    throw 42;
}
catch (int e) {  // 捕获 int 类型异常
    std::cout << "Caught an integer: " << e << std::endl;
}
catch (std::exception& e) {  // 捕获所有继承自 std::exception 的异常
    std::cout << "Caught exception: " << e.what() << std::endl;
}

3. 通用的异常捕获

如果你不确定抛出的异常类型,可以使用一个通用的 catch(...) 来捕获所有未明确捕获的异常。

try {
    // 代码可能抛出不同类型的异常
    throw "Something went wrong";
}
catch (...) {  // 捕获所有类型的异常
    std::cout << "Caught an unknown exception" << std::endl;
}

4. 异常传递

当一个异常被抛出后,程序会按照“栈展开”的方式逐级寻找匹配的 catch 块。找不到时,程序会终止。

例如,如果 main() 中的 catch 无法捕获异常,异常将会沿着调用栈传递,直到程序终止。

5. 多重异常处理

你可以使用多个 catch 块来捕获不同类型的异常,确保程序对各种错误情况作出处理。

try {
    throw std::out_of_range("Out of range error");
}
catch (const std::out_of_range& e) {
    std::cout << "Caught out_of_range: " << e.what() << std::endl;
}
catch (const std::exception& e) {
    std::cout << "Caught exception: " << e.what() << std::endl;
}
catch (...) {
    std::cout << "Caught unknown exception" << std::endl;
}

6. 异常的传播

C++ 允许在多个函数中抛出异常。当函数内的代码抛出异常时,控制权会跳转到调用该函数的地方。如果异常未被捕获,则程序会终止。

void funcA() {
    throw std::runtime_error("Error in funcA");
}

void funcB() {
    funcA();  // 异常从 funcA 传播到 funcB
}

int main() {
    try {
        funcB();
    }
    catch (const std::exception& e) {
        std::cout << "Caught in main: " << e.what() << std::endl;
    }
}

7. 自定义异常

你可以定义自定义的异常类型,通过继承 std::exception 或其他异常类来创建自己的异常类。

class MyException : public std::exception {
public:
    const char* what() const noexcept override {
        return "My custom exception occurred";
    }
};

void test() {
    throw MyException();  // 抛出自定义异常
}

int main() {
    try {
        test();
    }
    catch (const MyException& e) {
        std::cout << "Caught custom exception: " << e.what() << std::endl;
    }
}

C++ 标准库异常类概述

C++ 标准库定义了一些通用的异常类,它们位于 <stdexcept> 头文件中。这些异常类帮助程序员识别和处理不同类型的错误。C++ 标准库异常类通常都继承自 std::exception,这是所有标准异常类的基类。

1. std::exception

std::exception 是 C++ 标准库异常体系的基类。它提供了一个虚函数 what(),返回一个指向常量字符数组的指针,用于描述异常的相关信息。

  • 定义

    class exception {
    public:
        virtual const char* what() const noexcept;
    };
    
    • what() 方法返回异常信息的描述。

    • noexcept 说明该函数不会抛出异常。

std::exception 是所有标准异常类的父类。如果你创建自定义的异常类,可以继承 std::exception 来提供异常描述。

示例

#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::exception();
    }
    catch (const std::exception& e) {
        std::cout << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Caught exception: 

2. std::runtime_error

std::runtime_error 继承自 std::exception,表示程序在运行时遇到的错误,通常是不可预料的错误。它的构造函数接受一个描述错误的字符串,该字符串将通过 what() 方法返回。

  • 定义

    class runtime_error : public exception {
    public:
        explicit runtime_error(const char* what_arg);
        explicit runtime_error(const std::string& what_arg);
    };
    

示例

#include <iostream>
#include <stdexcept>

int main() {
    try {
        throw std::runtime_error("Runtime error occurred!");
    }
    catch (const std::runtime_error& e) {
        std::cout << "Caught runtime_error: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Caught runtime_error: Runtime error occurred!

std::runtime_error 通常用于处理程序在运行时出现的异常情况,例如文件操作失败、网络连接错误等。

3. std::logic_error

std::logic_error 也继承自 std::exception,表示程序中的逻辑错误。这些错误通常是程序设计或实现上的错误,通常是程序员在编写程序时犯的错误。常见的逻辑错误包括访问无效的索引、非法的参数传递等。

  • 定义

    class logic_error : public exception {
    public:
        explicit logic_error(const char* what_arg);
        explicit logic_error(const std::string& what_arg);
    };
    

示例

#include <iostream>
#include <stdexcept>

void test(int x) {
    if (x < 0) {
        throw std::logic_error("Negative value passed");
    }
}

int main() {
    try {
        test(-1);  // 将抛出逻辑错误
    }
    catch (const std::logic_error& e) {
        std::cout << "Caught logic_error: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Caught logic_error: Negative value passed

std::logic_error 通常用于处理程序在设计上就不应该发生的错误。

4. std::out_of_range

std::out_of_range 继承自 std::logic_error,用于表示访问超出有效范围的错误。通常用于数组、容器、指针等操作超出有效范围时。

  • 定义

    class out_of_range : public logic_error {
    public:
        explicit out_of_range(const char* what_arg);
        explicit out_of_range(const std::string& what_arg);
    };
    

示例

#include <iostream>
#include <stdexcept>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    try {
        std::cout << vec.at(5) << std::endl;  // 访问越界元素
    }
    catch (const std::out_of_range& e) {
        std::cout << "Caught out_of_range: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Caught out_of_range: vector::_M_range_check

std::out_of_range 常用于检查容器操作时索引越界的情况。

5. std::invalid_argument

std::invalid_argument 继承自 std::logic_error,用于表示函数或操作接收到一个非法的参数。这通常是当函数的参数不符合预期时抛出的异常。

  • 定义

    class invalid_argument : public logic_error {
    public:
        explicit invalid_argument(const char* what_arg);
        explicit invalid_argument(const std::string& what_arg);
    };
    

示例

#include <iostream>
#include <stdexcept>

void test(int x) {
    if (x <= 0) {
        throw std::invalid_argument("Argument must be positive");
    }
}

int main() {
    try {
        test(0);  // 传递非法参数
    }
    catch (const std::invalid_argument& e) {
        std::cout << "Caught invalid_argument: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Caught invalid_argument: Argument must be positive

std::invalid_argument 通常用于检测函数参数的合法性。

6. std::length_error

std::length_error 继承自 std::logic_error,用于表示容器或其他数据结构在处理时超过了其最大容量。比如在向一个固定大小的容器中插入元素时,超出了容器的最大长度。

  • 定义

    class length_error : public logic_error {
    public:
        explicit length_error(const char* what_arg);
        explicit length_error(const std::string& what_arg);
    };
    

示例

#include <iostream>
#include <stdexcept>
#include <vector>

int main() {
    try {
        std::vector<int> vec(10);
        vec.resize(100);  // 超出容器允许的长度
    }
    catch (const std::length_error& e) {
        std::cout << "Caught length_error: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Caught length_error: vector::resize

std::length_error 用于指示容器长度超过限制。

7. std::overflow_error

std::overflow_error 继承自 std::runtime_error,表示算术操作发生溢出(如整数加法超出了可表示的范围)。这种错误通常发生在数值计算时。

  • 定义

    class overflow_error : public runtime_error {
    public:
        explicit overflow_error(const char* what_arg);
        explicit overflow_error(const std::string& what_arg);
    };
    

示例

#include <iostream>
#include <stdexcept>

int main() {
    try {
        int a = 2147483647;  // 假设int是32位,最大值为2147483647
        a = a + 1;  // 发生溢出
        throw std::overflow_error("Integer overflow");
    }
    catch (const std::overflow_error& e) {
        std::cout << "Caught overflow_error: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Caught overflow_error: Integer overflow

std::overflow_error 用于表示溢出错误。

8. std::underflow_error

std::underflow_error 继承自 std::runtime_error,表示算术操作发生下溢(例如浮点数计算的下溢)。

更多的异常类: C++ 异常处理
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

纯css实现环形进度条

需要在中实现一个定制化的环形进度条&#xff0c;最终效果如图&#xff1a; 使用代码 <divclass"circular-progress":style"{--progress: nextProgress,--color: endSliderColor,--size: isFull ? 60rpx : 90rpx,}"><div class"inner-conte…

0基础 | 硬件 | 电源系统 一

降压电路LDO 几乎所有LDO都是基于此拓扑结构 图 拓扑结构 LDO属于线性电源&#xff0c;通过控制开关管的导通程度实现稳压&#xff0c;输出纹波小&#xff0c;无开关噪声 线性电源&#xff0c;IoutIin&#xff0c;发热功率P电压差△U*电流I&#xff0c;转换效率Vo/Vi LDO不适…

获取KUKA机器人诊断文件KRCdiag的方法

有时候在进行售后问题时需要获取KUKA机器人的诊断文件KRCdiag&#xff0c;通过以下方法可以获取KUKA机器人的诊断文件KRCdiag&#xff1a; 1、将U盘插到控制柜内的任意一个USB接口&#xff1b; 2、依次点【主菜单】—【文件】—【存档】—【USB&#xff08;控制柜&#xff09…

一周学会Pandas2 Python数据处理与分析-NumPy数据类型

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili NumPy 提供了丰富的数据类型&#xff08;dtypes&#xff09;&#xff0c;主要用于高效数值计算。以下是 NumPy 的主要…

Redis核心机制-缓存、分布式锁

目录 缓存 缓存更新策略 定期生成 实时生成 缓存问题 缓存预热&#xff08;Cache preheating&#xff09; 缓存穿透&#xff08;Cache penetration&#xff09; 缓存雪崩&#xff08;Cache avalanche&#xff09; 缓存击穿&#xff08;Cache breakdown&#xff09; 分…

如何在Ubuntu上安装Dify

如何在Ubuntu上安装Dify 如何在Ubuntu上安装docker 使用apt安装 # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg…

Python FastApi(13):APIRouter

如果你正在开发一个应用程序或 Web API&#xff0c;很少会将所有的内容都放在一个文件中。FastAPI 提供了一个方便的工具&#xff0c;可以在保持所有灵活性的同时构建你的应用程序。假设你的文件结构如下&#xff1a; . ├── app # 「app」是一个 Python 包…

【算法竞赛】状态压缩型背包问题经典应用(蓝桥杯2019A4分糖果)

在蓝桥杯中遇到的这道题&#xff0c;看上去比较普通&#xff0c;但其实蕴含了很巧妙的“状态压缩 背包”的思想&#xff0c;本文将从零到一&#xff0c;详细解析这个问题。 目录 一、题目 二、思路分析&#xff1a;状态压缩 最小覆盖 1. 本质&#xff1a;最小集合覆盖问题…

常微分方程 1

slow down and take your time 定积分应用回顾常微分方程的概述一阶微分方程可分离变量齐次方程三阶线性微分方程 一阶线性微分方程不定积分的被积分函数出现了绝对值梳理微分方程的基本概念题型 1 分离变量题型 2 齐次方程5.4 题型 3 一阶线性微分方程知识点5.55.6 尾声 定积分…

Web前端页面搭建

1.在D盘中创建www文件 cmd进入窗口命令windowsR 切换盘符d: 进入创建的文件夹 在文件夹里安装tp框架 在PS中打开tp文件 创建网站&#xff0c;根目录到public 在浏览器中打开网页 修改文件目录名称 在public目录中的。htaccess中填写下面代码 <IfModule mod_rewrite.c >…

开源 LLM 应用开发平台 Dify 全栈部署指南(Docker Compose 方案)

开源 LLM 应用开发平台 Dify 全栈部署指南&#xff08;Docker Compose 方案&#xff09; 一、部署环境要求与前置检查 1.1 硬件最低配置 组件要求CPU双核及以上内存4GB 及以上磁盘空间20GB 可用空间 1.2 系统兼容性验证 ✅ 官方支持系统&#xff1a; Ubuntu 20.04/22.04 L…

BN 层的作用, 为什么有这个作用?

BN 层&#xff08;Batch Normalization&#xff09;——这是深度神经网络中非常重要的一环&#xff0c;它大大改善了网络的训练速度、稳定性和收敛效果。 &#x1f9e0; 一句话理解 BN 层的作用&#xff1a; Batch Normalization&#xff08;批归一化&#xff09;通过标准化每一…

金仓数据库KCM认证考试介绍【2025年4月更新】

KCM&#xff08;金仓认证大师&#xff09;认证是金仓KES数据库的顶级认证&#xff0c;学员需通过前置KCA、KCP认证才能考KCM认证。 KCM培训考试一般1-2个月一次&#xff0c;KCM报名费原价为1.8万&#xff0c;当前优惠价格是1万&#xff08;趋势是&#xff1a;费用越来越高&…

如何通过句块训练法(Chunks)提升英语口语

真正说一口流利英语的人&#xff0c;并不是会造句的人&#xff0c;而是擅长“调取句块”的人。下面我们从原理、方法、场景、资源几个维度展开&#xff0c;告诉你怎么用“句块训练法&#xff08;Chunks&#xff09;”快速提升英语口语&#xff1a; 一、什么是“句块”&#xff…

[ctfshow web入门]burpsuite的下载与使用

下载 吾爱破解网站工具区下载burpsuite https://www.52pojie.cn/thread-1544866-1-1.html 本博客仅转载下载链接&#xff0c;下载后请按照说明进行学习使用 打开 配置 burpsuite配置 burpsuite代理设置添加127.0.0.1:8080 浏览器配置 如果是谷歌浏览器&#xff0c;打开win…

vscode集成deepseek实现辅助编程(银河麒麟系统)【详细自用版】

针对开发者用户&#xff0c;可在Visual Studio Code中接入DeepSeek&#xff0c;实现辅助编程。 可参考我往期文章在银河麒麟系统环境下部署DeepSeek&#xff1a;基于银河麒麟桌面&&服务器操作系统的 DeepSeek本地化部署方法【详细自用版】 一、前期准备 &#xff08…

elementui的默认样式修改

今天用element ui &#xff0c;做了个消息提示&#xff0c;发现提示的位置总是在上面&#xff0c;如图&#xff1a; 可是我想让提示的位置到下面来&#xff0c;该怎么办&#xff1f; 最后还是看了官方的api 原来有个自定义样式属性 customClass 设置下就好了 js代码 css代码 效…

基于STM32的智能门禁系统设计与实现

一、项目背景与功能概述 在物联网技术快速发展的今天&#xff0c;传统门锁正在向智能化方向演进。本系统基于STM32F103C8T6微控制器&#xff0c;整合多种外设模块&#xff0c;实现了一个具备以下核心功能的智能门禁系统&#xff1a; 密码输入与验证&#xff08;4x3矩阵键盘&a…

基于SpringBoot的河道水情大数据可视化分析平台设计与实现(源码+论文+部署讲解等)

需要资料&#xff0c;请文末联系 一、平台介绍 水情监测数据大屏 - 平台首页 日均水位 日均水速 二、论文内容 摘要&#xff08;中文&#xff09; 本文针对河道水情监测领域的数据管理和可视化分析需求&#xff0c;设计并实现了一套河道水情大数据可视化分析平台。该平台基…

广告推荐算法:COSMO算法与A9算法的对比

COSMO算法与A9算法的概念解析 1. A9算法 定义与背景&#xff1a; A9算法是亚马逊早期为电商平台研发的核心搜索算法&#xff0c;主要用于优化商品搜索结果的排序和推荐&#xff0c;其核心逻辑围绕产品属性与关键词匹配展开。自2003年推出以来&#xff0c;A9通过分析商品标题…