• C++ Primer 5th 第18章 用于大型程序的工具


    C++大规模程序设计至少存在三个特殊要求:

    • 错误处理
    • 库的引入
    • 复杂建模

    以上三种对应C++语言的三种特性:异常处理、命名空间、多重继承。

    异常处理

    异常处理机制是一种允许偷懒的工具,在出现非正确的情况时,进行错误之间的协作处理。异常使得问题检测和解决过程分离开来。程序的一部分检测问题,另一个部分专门解决问题。

    抛出异常

    在C++中通过抛出一个表达式来引发异常,被抛出的表达式的类型以及当前调用链共同决定哪个部分来处理异常。被选择的部分是调用链和抛出类型匹配最近的处理部分。根据抛出类型的类型及其内容,处理部分能够得知到底发生了什么错误。

    当使用throw进行异常抛出时,throw语句后的下一条代码语句不再被执行,程序的执行控制权跳转到匹配的异常处理catch模块。该catch模块可能和异常抛出部分同属一个函数体,也可能是直接或间接调用链上的函数中。这会导致两个结果:

    • 沿着调用链的函数可能会提早退出
    • 一旦开始进行异常处理,调用链上创建的对象会被销毁(对类类型对象来说,会执行析构函数)

    举个例子来说:A函数调用了B函数,B函数又调用了C函数,这形成了一个栈式的调用链A->B->C,C函数中途错误并抛出了一个异常,C函数没有异常处理部分,因此逆序回溯调用链回到B,而B也没有异常处理部分,继续逆序回溯调用链回到A,A中含有异常处理部分,因此异常在A中被处理消化,这其中B和C都没有正常结束,它们都提早退出了。另外,由于最终异常在A中处理,那么B和C执行到一半时之前已经创建的那些对象都会被销毁。throw的作用类似于return。

    栈展开

    当程序抛出一个异常之后,程序暂停当前函数执行,并立即开始沿着调用链查找catch处理部分。当throw出现在一个try语句块中时,编译器检查与该try配对的catch语句,如果找到且匹配,那么就使用该catch处理。如果没找到,则在外层作用域中查找匹配的。如果找遍当前函数都无法找到,那么退出该函数,逆序回溯调用链继续前面的方法继续查找,最终要么找到调用匹配的进行处理,要么没有找到调用terminate终止程序。上述这个查找的过程被称为栈展开。当找到匹配的catch处理之后,程序将在匹配的catch处理模块之后的非catch模块开始执行。

    在栈展开的过程中,调用链上创建的局部对象会被销毁。对类类型对象来说,会执行析构函数,因此通常来说,析构函数不允许再抛出异常,应该在析构函数内部把异常消化掉。

    异常对象

    异常对象是一种特殊的对象,编译器使用异常抛出表达式来对异常对象进行拷贝初始化,如果该表达式是一个类类型,则该类析构函数和拷贝或移动构造函数必须正常,如果表达式是一个数组或函数类型,则表达式会退化成相应的指针类型。

    异常对象在使用完毕后会被销毁,另外,在栈展开过程中,调用链上的函数可能会提早退出,所以不允许抛出一个指向局部变量的指针。

    捕获异常

    catch子句的语法同函数类似,拥有一个形参列表和函数体,但没有返回值。同函数的形参类似,catch的形参列表也可以没有形参名,而只有一个形参类型,或者形参是一个左值引用(不允许是右值引用)。

    异常的处理catch语句的搜索过程,并不会根据最佳匹配来挑选,而是根据顺序,因此约束专门的catch语句越应该排在前面,尤其是在继承体系中,派生类应该在基类前。

    异常对象匹配时,是不允许类型转换的,只允许const可以绑定到非const上,数组退化指针,派生类转换为基类,除此之外,任何类型转换都不允许,即使是double向int这样的内置类型间的转换。

    重新抛出

    有时,一个catch子句并不能把所有问题处理妥当,此时允许该catch重新抛出,通过重新抛出将异常传递给另外的catch子句,重新抛出的语法是使用一个throw语句,不含任何表达式:

    throw;

    该throw语句只能出现在catch子句之内或者嵌套在catch子句更深的内部,否则编译器会调用terminate。重新抛出的对象如果是以引用方式获得的,那么catch中的更改才能得以保留。

    捕获任意类型的异常

    有时候,我们对所有的异常处理都是使用同一种方法而不论异常的类型是什么,这时可以通过特殊的语法捕获所有异常,方法如下:

    catch( ... )
    {
        ...
    }

    通过使用省略符号( ... )来作为catch子句的参数,这样能匹配所有的异常,如前面提及的:catch子句不是根据最佳类型匹配,而是根据顺序匹配。因此,通用的错误匹配捕获语句一般防止catch列表的最后。

  • 相关阅读:
    bootstrap
    前端框架 angularjs
    JAva集合框架
    圣诞
    IDEA
    科目三
    Bootstrap简介及Bootstrap里的栅格系统col-md/sm/xs-x;
    C# Windows service 定时发邮件功能 (用到webService)
    <转> 数据库索引的作用和优点缺点
    小知识
  • 原文地址:https://www.cnblogs.com/pluse/p/5998669.html
Copyright © 2020-2023  润新知