1. 首页
  2. c++

#《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.”

本文来自投稿,不代表程序员编程网立场,如若转载,请注明出处:http://www.cxybcw.com/189065.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code