技术分享
😎C++-异常
00 min
2021-7-2
2024-9-24
type
status
summary
date
slug
tags
category
icon
password

C++-异常

异常其实是在C++中较为常用的一种用法,在c语言中处理异常的方式就是终止程序和返回错误,但是这样就会在代码量较大的情况下很难发现到底是在哪个模块出现问题,所以在C++中推出了新的处理异常方法

1.异常概念

异常是一种处理错误的一种方式,当一个函数出现异常发现自己无法处理的时候就可以抛出异常,让函数的直接或者间接掉用者来处理这个异常
1.异常是通过抛出对象引发的,该对象的类型决定了激活哪个try catch的处理代码
2.被选中的代码是调用链中与该对象类型最匹配距离最近的那个
3.抛出异常对象后,会生成一个异常对象的拷贝
4.catch能捕获任意类型的异常,但是不知道是什么类型的对象
5.实际中抛出异常和捕获的原则有一个例外,不是类型完全匹配,可以抛出的派生类对象,使用基类捕获,在实际中非常有用,在本文的下面会讲到

2.在函数调用链中异常栈展开捕获匹配原则

1.首先检查throw是否在try内部,如果是再查找匹配的catch语句,如果有匹配的那么就调到匹配的catch的地方进行处理
2.如果没有匹配catch那么就退出当前栈,继续在调用函数的栈中查找匹配的catch
3.如果到了main函数的栈中都没有匹配的那么就直接终止程序
  1. 找到catch之后,进行catch里面的语句之后,会沿着catch之后的语句继续进行
 
每个公司(c++)一般都有自己的一套异常继承体系继承自最原本的Exception基类子类可能会定义:mysqlException,ipException
当然C++也有一些基本的exception库(但是定义的很一般,一般用的比较少)
 
参考一下cpp

3.异常安全和异常规范

1.其实在抛出异常的时候也经常导致其他的问题比如内存泄漏,,比如在new和delete之间抛出了异常,在lock和unlock之间抛出异常导致出现死锁,C++经常通过ROLL来解决问题,这里会在后续的智能指针文章中会详细讲解
2.异常规范,异常规格的说明其实就是想让函数使用者知道可能抛出的异常有哪些:
在throw后面列出可能出现的所有异常类型
如果函数后面姐throw()表示该函数不抛异常
3.其实在公司内部,都有自定义的一套异常体系,防止每个人都乱抛异常,导致代码混乱,这样大家都抛出一个派生类,捕获一个基类就可以了

4.异常的优缺点分析

优点

  1. 错误分离:异常处理允许将错误处理代码与常规代码逻辑分离,使得主程序流程更加清晰和易于维护。
  1. 错误传播:异常可以跨越多个函数调用层次向上传递,直到遇到相应的catch块。这使得错误处理可以在更高级别的抽象层次上进行。
  1. 类型安全:异常处理机制是类型安全的。你可以抛出任何类型的异常,并且可以针对不同类型的异常使用不同的catch块。
  1. 栈展开:当异常被抛出时,当前作用域内的所有局部对象都会被自动销毁,这称为栈展开。这有助于释放资源,防止内存泄漏。
  1. 资源管理:异常可以与资源管理相结合,例如使用RAII(Resource Acquisition Is Initialization)技术,确保即使在发生异常时也能正确地释放资源,这里在后文中的智能指针会讲解
  1. 不需要显式的错误码检查:与返回错误码相比,异常处理不需要在每个函数调用后进行错误检查,从而简化了代码。

缺点

  1. 性能开销:异常处理可能会带来性能开销。抛出和捕获异常涉及到栈展开和类型匹配,这些操作可能比简单的错误码检查更耗时,但是在现在硬件能力越来越强的时候,这个影响不大了
  1. 滥用风险:异常可能被滥用,导致代码逻辑混乱。有些开发者可能会将异常用于正常的控制流,这是不推荐的做法。
  1. 复杂性:异常处理增加了程序的复杂性,特别是在大型项目中,异常的传递和捕获可能会导致复杂的控制流。
  1. 难以调试:当异常被抛出时,栈展开可能会丢失调用栈的部分信息,使得调试变得更加困难。
  1. 不透明的错误处理:异常处理可能会隐藏错误处理逻辑,导致调用者不清楚某个函数可能抛出哪些异常。
  1. 不一致性:C++标准库和第三方库在异常使用上可能存在不一致性,有的函数可能抛出异常,有的则返回错误码,这要求开发者必须了解每个函数的行为。
  1. 违反契约:在某些情况下,异常可能会违反函数的隐式契约。例如,一个函数可能声明不会抛出异常,但如果它调用了会抛出异常的函数,那么这种声明就被违反了。
总结来说,C++的异常处理机制是一种强大的工具,但它的使用需要谨慎和有节制。开发者应该根据具体情况和项目需求来决定是否使用异常,以及如何使用。
 
 
上一篇
容器-Map&Set
下一篇
数据结构-AVL树