C++ - 异常类体系(exception class hierarchy)

参考:

  1. 《Essential C++》
  2. C++ exception类

C++标准库定义了一套异常类体系(exception class hierarchy),其根部是名为exception的抽象基类,标准库抛出的异常都是 exception 的子类,称为标准异常(Standard Exception)。exception声明有一个what()虚函数,会返回一个const char *,用以表示被抛出异常的文字描述。
可以通过下面的语句来捕获所有的标准异常:

try{
    // 可能抛出异常的语句
}catch(const exception &e){
    // 处理异常的语句
    // std::cerr << ex.what() << std::endl; 
}

之所以使用引用,是为了提高效率。如果不使用引用,就要经历一次对象拷贝(要调用拷贝构造函数)的过程。

exception 类位于 头文件中,它被声明为:

class exception{
public:
    exception () throw();  //构造函数
    exception (const exception&) throw();  //拷贝构造函数
    exception& operator= (const exception&) throw();  //运算符重载
    virtual ~exception() throw();  //虚析构函数
    virtual const char* what() const throw();  //虚函数
}

我们可以将自己编写的iterator_overflow继承于exception基类之下。首先必须包含标准头文件exception,而且必须提供自己的what():
iterator_overflow.h :

#ifndef ITERATOR_OVERFLOW_H
#define ITERATOR_OVERFLOW_H

#include <iostream>
#include <exception>

class iterator_overflow : public std::exception
{
public:
    iterator_overflow(int index, int max)
        : _index(index), _max(max) {}

    int index() { return _index; }
    int max() { return _max; }

    // 不继承exception时作为独立的异常类。
    // void what_happened(std::ostream &os = std::cerr)
    // {
    // os << "Internal error: current index "
    //    << _index << " exceeds maximum bound: "
    //    << _max;
    // }

    // 覆盖 exceptions::what()
    // const char *what() const;
    // 以上代码会报错:
    // looser throw specifier for 'virtual const char* iterator_overflow::what() const'gcc
    // 原因如下:
    // Since c++11 what() is noexcept. 
    // You have not declared it as noexcept. 
    // That is what the 'looser throw specifier' is telling you. 
    // See http://en.cppreference.com/w/cpp/error/exception/what.

    virtual const char *what() const noexcept override;

private:
    int _index;
    int _max;
};

#endif

将iterator_overflow融入标准的exception类体系的好处是,它可以被任何“打算捕获抽象基类exception”的程序代码所捕获。这意味着我们不必修改原有的程序代码,就可以让那些程序代码认识这个class。
下面是iterator_overflow中what()的具体实现:
operator_overflow.cpp :

#include <sstream>
#include <string>
#include "iterator_overflow.h"

const char *
iterator_overflow::
    what() const noexcept
{
    std::ostringstream ex_msg;
    static std::string msg;

    // 将输出信息写到内存的ostringstream对象之中。
    // 将整数值转为字符串表示。

    ex_msg << "Internal error: current index "
           << _index << " exceeds maximum bound: "
           << _max;

    // 萃取出string对象。
    msg = ex_msg.str();

    // 萃取出const char*表达式。
    return msg.c_str();
}

noexcept 用于描述函数不会抛出异常,一旦有异常抛出,会立刻终止程序,它可以阻止异常的传播与扩散。noexcept可以带一个“常量表达式”作为参数,常量表达式为true,表示不会抛出异常,否则代表可以抛出异常。

exception 类的直接派生类:

异常名称说明
logic_error逻辑错误。
runtime_error运行时错误。
bad_alloc使用 new 或 new[ ] 分配内存失败时抛出的异常。
bad_typeid使用 typeid 操作一个 NULL 指针,而且该指针是带有虚函数的类,这时抛出 bad_typeid 异常。
bad_cast使用 dynamic_cast 转换失败时抛出的异常。
ios_base::failureio 过程中出现的异常。
bad_exception这是个特殊的异常,如果函数的异常列表里声明了 bad_exception 异常,当函数内部抛出了异常列表中没有的异常时,如果调用的 unexpected() 函数中抛出了异常,不论什么类型,都会被替换为 bad_exception 类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值