C++的异常捕获、异常安全、noexcpt关键字(重要)

目录

C语言的异常处理方式

C++的异常处理方式

标准异常类std::exception

自定义异常类

异常安全

C++98的异常规范

noexcpt关键字

异常的优点

异常的缺点


C语言的异常处理方式

基本概念:C 语言中没有专门的异常处理机制,主要使用 返回错误码 和 assert断言 

返回错误码:相关变量与函数有errno、perror、sterror

  • errno 是一个全局变量,用于存储上一个函数调用出错的错误码
  • strerror 是一个函数,它接收 errno 的值,返回该错误码对应的错误信息字符串
  • perror 是用于自动打印 errno 对应的错误信息的函数,同时还接受一个用户自定义的信息,在打印错误时会将该自定义信息与错误码对应的信息进行拼接,是printf("自定义信息",sterror(errno))的简化版
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
    FILE *file = fopen("nonexistent_file.txt", "r");
    if (!file) {
        // 打印错误码
        printf("错误码:%d\n", errno);
        // 使用 strerror 获取错误信息
        printf("错误信息:%s\n", strerror(errno));
        // 使用 perror 打印用户信息+错误信息
        perror("文件打开失败");
    }
    return 0;
}

  • 优点:灵活,不会强制程序终止,可以允许程序根据情况选择是否终止或尝试恢复
  • 缺点:调用后需要手动检查返回值,不小心忽略时可能导致错误未被处理

assert断言是一种常见的用于检查异常情况的宏,位于 <assert.h> assert(expression) 检查表达式 expression 是否为 true,若为 false 则打印错误信息并终止程序。常用于调试或保证程序关键状态的正确性(如检查指针非空、避免非法内存访问等)

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>

int divide(int a, int b) {
    assert(b != 0);  // 使用断言处理严重错误
    return a / b;
}

int main() {
    int result = divide(10, 0);  // 断言,直接终止程序
    printf("结果是:%d\n", result);
    return 0;
}

  • 优点:快速、简单地捕捉严重错误
  • 缺点:assert 会导致程序立即退出,且无法恢复,不适合在产品环境中处理非严重错误

C++的异常处理方式

基本概念:在 C++ 中,异常处理通常使用 trythrowcatch 关键字实现,可以帮助开发者能捕获程序在运行时抛出的异常和并进行处理,而不是使用返回值或错误码来检测错误

  • try块:用于包含可能引发异常的代码段
  • throw:用于抛出一个匿名的异常对象,throw 后,程序会停止当前 try 块中的执行,并转移到相应的 catch
  • catch块:用于捕获和处理特定类型的异常,catch 后必须跟一个参数类型,用于指定捕获的异常类型,捕获成功后,可以进行自定义的错误处理方式
#include <iostream>
#include <stdexcept>

void division(double a, double b) {
    if (b == 0)
        throw std::string("除数不能为零");  // 抛出异常
    std::cout << "结果: " << a / b << std::endl;
}

int main() {
    try {
        division(10, 0);  // 可能会抛出异常的代码
    }
    catch (const std::string& e) {  // 捕获 string 类型的异常
        std::cerr << "捕获到异常: " << e << std::endl;
    }
    catch (...) {  // 捕获所有异常类型
        std::cerr << "捕获到未知异常" << std::endl;
    }
    return 0;
}

注意事项:

1、不能在try块与catch块间、catch块与catch块间添加代码,一个try块后跟的所有catch块都是用于捕获该try块中throw的异常,且一个try块后必须跟至少一个catch块

try{...}
catch(string& e){...}
catch(...){...}

2、throw的是某个类的匿名对象(也称异常对象)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值