C++11 异常(下)

简介: C++11 异常(下)

自定义异常

实际中很多公司都会自定义自己的异常体系进行规范的异常管理

  • 公司中的项目一般会进行模块划分 让不同的程序员或小组完成不同的模块 如果不对抛异常这件事进行规范那么负责最外层捕获异常的程序员就非常难受了 因为他需要捕获大家抛出的各种类型的异常对象
  • 因此实际中都会定义一套继承的规范体系 先定义一个最基础的异常类 所有人抛出的异常对象都必须是继承于该异常类的派生类对象 因为异常语法规定可以用基类捕获抛出的派生类对象 因此最外层就只需捕获基类就行了

76398c3f89e441fb8ada2103c5da6584.png

下面是基础的异常类代码展示

class Exception
{
public:
  Exception(int errid, const char* errmsg)
    :_errid(errid)
    , _errmsg(errmsg)
  {}
  int GetErrid() const
  {
    return _errid;
  }
  virtual string what() const
  {
    return _errmsg;
  }
protected:
  int _errid;     //错误编号
  string _errmsg; //错误描述
  //...
};

这里基类异常类中有两个保护成员分别是错误编号和错误描述

它还有一个虚函数waht()来发出错误描述

接着我们来看它的子类对象

class CacheException : public Exception
{
public:
  CacheException(int errid, const char* errmsg)
    :Exception(errid, errmsg)
  {}
  virtual string what() const
  {
    string msg = "CacheException: ";
    msg += _errmsg;
    return msg;
  }
protected:
  //...
};
class SqlException : public Exception
{
public:
  SqlException(int errid, const char* errmsg, const char* sql)
    :Exception(errid, errmsg)
    , _sql(sql)
  {}
  virtual string what() const
  {
    string msg = "CacheException: ";
    msg += _errmsg;
    msg += "sql语句: ";
    msg += _sql;
    return msg;
  }
protected:
  string _sql; //导致异常的SQL语句
  //...
};

这里要说明两点

  • 因为在子类中要使用父类的成员变量 所以父类中的成员变量不能是私有的
  • 基类Exception中的what成员函数最好定义为虚函数 方便子类对其进行重写 从而达到多态的效果


标准异常库

下面是C++中的标准异常库体系

4b177e1ec5484f20b46108a241a300f5.png下表是对上面继承体系中出现的每个异常的说明

d249218bcf984118ae3bc6e63ee4a592.png


异常的优缺点

优点:

  1. 异常对象定义好了 相比错误码的方式可以清晰准确的展示出错误的各种信息 甚至可以包含堆栈调用等信息 这样可以帮助更好的定位程序的bug。
  2. 返回错误码的传统方式有个很大的问题就是 在函数调用链中 深层的函数返回了错误 那么我们得层层返回错误码 最终最外层才能拿到错误。
  3. 很多的第三方库都会使用异常 比如boost、gtest、gmock等等常用的库,如果我们不用异常就不能很好的发挥这些库的作用
  4. 很多测试框架也都使用异常 因此使用异常能更好的使用单元测试等进行白盒的测试
  5. 部分函数使用异常更好处理 比如T& operator这样的函数 如果pos越界了只能使用异常或者终止程序处理 没办法通过返回值表示错误。


缺点

  1. 异常会导致程序的执行流乱跳 并且非常的混乱 这会导致我们跟踪调试以及分析程序时比较困难
  2. 异常会有一些性能的开销 当然在现代硬件速度很快的情况下 这个影响基本忽略不计
  3. C++没有垃圾回收机制 资源需要自己管理 有了异常非常容易导致内存泄露 死锁等异常安全问题 这个需要使用RAII来处理资源的管理问题 学习成本比较高
  4. C++标准库的异常体系定义得不够好 导致大家各自定义自己的异常体系 非常的混乱
  5. 异常尽量规范使用 否则后果不堪设想 随意抛异常 也会让外层捕获的用户苦不堪言
  6. 异常接口声明不是强制的 对于没有声明异常类型的函数 无法预知该函数是否会抛出异常


思维导图

985ec6c4b8d04d3fbe3557fae04a43d2.png

相关文章
|
8月前
|
算法 编译器 C语言
【C++ 异常】C++ 标准库异常类及其应用
【C++ 异常】C++ 标准库异常类及其应用
106 0
|
8月前
|
安全 算法 C++
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误(三)
【C++ 异常 】深入了解C++ 异常机制中的 terminate()处理 避免不必要的错误
172 0
|
8月前
|
存储 安全 算法
【C/C++ 关键字 函数说明符 】C++ noexcept 关键字(指定某个函数不抛出异常)
【C/C++ 关键字 函数说明符 】C++ noexcept 关键字(指定某个函数不抛出异常)
104 0
|
2月前
|
安全 程序员 编译器
【C++】异常
C++异常处理机制允许在程序运行时出现错误时,通过`try`、`catch`和`throw`关键字将错误信息传递回调用栈,进行异常处理。它支持异常的重新抛出、自定义异常体系以及标准库提供的异常类层次结构,如`std::exception`及其派生类。异常处理提高了代码的健壮性和可维护性,但也带来了性能开销和代码复杂性等问题。合理使用异常机制,可以有效提升程序的稳定性和安全性。
64 3
|
8月前
|
SQL 安全 程序员
C++:异常
C++:异常
75 7
|
8月前
|
小程序 编译器 Linux
C++ 异常原理:以一个小程序为例
作者在调查某个 bug 时涉及到 C++ 异常,借此机会以本文把 C++ 异常机制梳理清楚供大家参考。
|
8月前
|
安全 Java 程序员
【C++】异常 -- 详解
【C++】异常 -- 详解
|
6月前
|
C++
C++ 异常机制问题之捕获异常的问题如何解决
C++ 异常机制问题之捕获异常的问题如何解决
|
6月前
|
安全 Java 程序员
【C++11】异常知多少
【C++11】异常知多少
59 7
|
5月前
|
安全 Java 程序员