C++异常详细介绍

简介: C++异常详细介绍

C++异常是一种处理程序运行时错误的机制,它允许程序在检测到错误时跳转到预定义的错误处理代码,而不必通过函数返回值层层传递错误信息。

异常的基本概念

  • 异常抛出(throw):当程序检测到错误时,使用throw关键字抛出一个异常对象
  • 异常捕获(catch):使用try-catch块捕获并处理抛出的异常
  • 异常传播:如果当前函数不能处理异常,异常会沿着函数调用栈向上传播,直到找到合适的处理代码

异常处理的基本语法

try {
   
    // 可能抛出异常的代码
    if (error_condition) {
   
        throw exception_object; // 抛出异常
    }
}
catch (exception_type1 e) {
   
    // 处理type1类型的异常
}
catch (exception_type2 e) {
   
    // 处理type2类型的异常
}
catch (...) {
   
    // 处理所有其他类型的异常(通配符)
}

异常类型

C++允许抛出任何类型的异常,包括:

  1. 基本数据类型:如intchar

    throw 404; // 抛出整数异常
    throw "Not found"; // 抛出字符串字面量异常
    
  2. 自定义类型:通常是类或结构体

    class MyException {
         
    private:
        string message;
    public:
        MyException(string msg) : message(msg) {
         }
        string getMessage() const {
          return message; }
    };
    
    // 抛出自定义异常
    throw MyException("发生了错误");
    
  3. 标准库异常:C++标准库提供了一系列异常类,定义在<exception>头文件中,主要包括:

    • std::exception:所有标准异常的基类
    • std::runtime_error:运行时错误
    • std::logic_error:逻辑错误
    • std::out_of_range:超出范围错误(如数组越界)
    • std::invalid_argument:无效参数错误

异常规范(C++11前)

早期C++允许使用异常规范指定函数可能抛出的异常类型:

// 声明该函数可能抛出int或string类型的异常
void func() throw(int, string) {
   
    // ...
}

// 声明该函数不抛出任何异常
void func() throw() {
   
    // ...
}

C++11引入了noexcept关键字替代异常规范:

// 声明该函数不会抛出任何异常
void func() noexcept {
   
    // ...
}

// 条件性noexcept
void func() noexcept(condition) {
   
    // ...
}

异常处理的最佳实践

  1. 只在异常情况下使用异常:不要将异常用于常规控制流
  2. 捕获适当的异常类型:避免过度使用catch(...)
  3. 按引用捕获异常:避免异常对象的复制,同时允许捕获派生类异常
    catch (const MyException& e) {
          // 推荐使用const引用
        // ...
    }
    
  4. 清理资源:使用RAII(资源获取即初始化)技术确保资源正确释放
  5. 异常安全:设计函数时考虑异常发生时的状态一致性

异常的优缺点

优点

  • 分离正常代码和错误处理代码,提高可读性
  • 可以在调用链的任意层次处理异常,不必每层都检查错误
  • 能够传递更丰富的错误信息

缺点

  • 可能影响性能(异常处理代码通常不被编译器优化)
  • 过度使用会使程序逻辑变得复杂
  • 可能导致资源泄露(如果没有正确处理)

示例:完整的异常处理程序

#include <iostream>
#include <stdexcept>
#include <string>

using namespace std;

// 除法函数,当除数为0时抛出异常
double divide(double num, double den) {
   
    if (den == 0) {
   
        throw invalid_argument("除数不能为0");
    }
    return num / den;
}

int main() {
   
    try {
   
        double result = divide(10, 0);
        cout << "结果: " << result << endl;
    }
    catch (const invalid_argument& e) {
   
        cerr << "错误: " << e.what() << endl;
    }
    catch (...) {
   
        cerr << "发生了未知错误" << endl;
    }

    return 0;
}

这个例子中,divide函数在检测到除数为0时抛出invalid_argument异常,main函数中的try-catch块捕获并处理这个异常,确保程序能够优雅地处理错误情况。

目录
相关文章
|
算法 编译器 C语言
【C++ 异常】C++ 标准库异常类及其应用
【C++ 异常】C++ 标准库异常类及其应用
222 0
|
安全 算法 C++
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误(三)
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误
298 0
|
4月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
138 0
|
12月前
|
安全 程序员 编译器
【C++】异常
C++异常处理机制允许在程序运行时出现错误时,通过`try`、`catch`和`throw`关键字将错误信息传递回调用栈,进行异常处理。它支持异常的重新抛出、自定义异常体系以及标准库提供的异常类层次结构,如`std::exception`及其派生类。异常处理提高了代码的健壮性和可维护性,但也带来了性能开销和代码复杂性等问题。合理使用异常机制,可以有效提升程序的稳定性和安全性。
224 3
|
SQL 安全 程序员
C++:异常
C++:异常
145 7
|
小程序 编译器 Linux
C++ 异常原理:以一个小程序为例
作者在调查某个 bug 时涉及到 C++ 异常,借此机会以本文把 C++ 异常机制梳理清楚供大家参考。
|
安全 Java 程序员
【C++】异常 -- 详解
【C++】异常 -- 详解
C++ 异常机制问题之捕获异常的问题如何解决
C++ 异常机制问题之捕获异常的问题如何解决
149 2
|
安全 Java 程序员
【C++11】异常知多少
【C++11】异常知多少
131 7
|
安全 Java 程序员