zoukankan      html  css  js  c++  java
  • #《Essential C++》读书笔记# 第七章 异常处理

    基础知识

    异常处理机制有两个主要成分:异常的鉴定和发出,以及异常的处理方式。通常,不论是membe function和non-member function,都有可能产生异常以及处理异常。异常出现后,正常程序的执行便被暂停(suspended)。与此同时,异常处理机制开始搜索程序中有能力处理这一异常的地点。异常被处理完毕之后,程序的执行便会继续(resume),从异常处理点接着执行下去。

    所谓异常(exception)是某种对象,最简单的异常对象可以设计为整数或字符串。大部分时候,被抛出的异常都属于特定的异常类(也许形成一个继承体系)。

    我们可以利用单条或一连串的catch字句来捕获(catch)被抛出的异常对象。catch子句有三部分组成:关键字catch、小括号内的一个类型或对象、大括号内的一组语句(用以处理异常)。抛出的异常对象类型会被拿来逐一地和每个catch子句比对。如果类型符合,那么该catch子句的内容便会被执行,在通过所有catch子句之后,由正常程序重新接手。有时我们可能无法完成异常的完整处理过程,在记录信息之外,我们或许需要重新抛出(rethrow)异常,以寻求其它catch子句的协助,做进一步的处理,重新抛出时,只需写下关键字throw即可,它只能出现于catch子句中,它会将捕获的异常对象再一次抛出,并由另一个类型符合的catch子句接手处理。如果我们想要捕获任何类型的异常,可以使用一网打尽(catch-all)的方式,只需在异常声明部分指定省略号(…)即可。

    catch子句应该和try块相应而生。try块是以关键字try作为开始,然后是大括号内的一连串程序语句。catch子句放在try块的末尾,这表示如果try块内有任何异常发生,便由接下来的catch子句加以处理。

    当函数的try块发生某个异常,但并没有相应的catch子句将它捕获,此函数便会被中断,由异常处理机制接管,沿着“函数调用链”一路回溯,搜寻符合条件的catch子句。如果“函数调用链”不断被解开,一直回到main()还是找不到合适的catch子句,变调用标准库提供的terminate()——其默认行为是中断整个程序的执行。

    练习题答案

    练习7.3 为练习5.2的Stack类体系加入两个异常类型,处理“想从空stack中取出元素”和“想为满stack添加元素”两种错误。请显示修改后的pop()和push()。

    定义PopOnEmpty和PushOnFull两个异常类,分别供pop()和push()抛出。于是,Stack的所有member function就不再需要返回代表成功或失败的值了:

    void pop(elemType& elem)
    {
        if (empty())
            throw PopOnEmpty;
        elem = _stack[--_top];
        _stack.pop_back();
    }
    
    void push(const elemType& elem)
    {
        if (!full())
        {
            _stack.push_back(elem);
            ++_top;
            return;
        }
        throw PushOnFull();
    }

    为了让这两个Stack异常可以被完全不知情的其它组件捕获,它们应该融入StackException继承体系中,后者又应该派生自标准库所提供的logic_error class。

    logic_error派生自exception。exception是标准库的所有异常类别继承体系的最根本抽象基类。这个继承体系有一个名为what()的虚函数,会返回const char*,用以表示被捕获的异常究竟为何。

    class StackException :public logic_error
    {
    public:
        StackException(const char* what) :_what(what) {}
        const char* what() const { return _what.c_str(); }
    
    protected:
        string _what;
    };
    
    class PopOnEmpty :public StackException
    {
    public:
        PopOnEmpty() :StackException("Pop on Empty Stack") {}
    };
    
    class PushOnFull :public StackException
    {
    public:
        PushOnFull() :StackException("Push on Full Stack") {}
    };

    以下任何一个catch子句都能够处理类型为PushOnFull的异常:

    catch (const PushOnFull & pof)
    {
        log(pof.what());
        return;
    }
    catch (const StackException & stke)
    {
        log(stke.what());
        return;
    }
    catch (const logic_error & lge)
    {
        log(lge.what());
        return;
    }
    catch (const PushOnFull & ex)
    {
        log(ex.what());
        return;
    }

    end。

    “A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.”

  • 相关阅读:
    [虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(二)
    PHP中PDO的配置与说明
    PHP输出表格的方法
    打印网格版本9*9乘法表
    js中日历的代码
    js中初学函数的使用
    c#中的23种设计模式
    用多态来实现U盘,Mp3,移动硬盘和电脑的对接,读取写入数据。
    用面向对象多态的思想分别去求圆形和长方形的面积和周长
    面向对象之多态(抽象类)
  • 原文地址:https://www.cnblogs.com/zhuifeng17/p/12316666.html
Copyright © 2011-2022 走看看