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列表的最后。
C++ Primer 5th 第18章 用于大型程序的工具的更多相关文章
- 【c++ Prime 学习笔记】第18章 用于大型程序的工具
大规模应用程序的特殊要求包括: 在独立开发的子系统之间协同处理错误:异常处理 使用各种库(可能包含独立开发的库)进行协同开发:命名空间 对比较复杂的应用概念建模:多重继承 18.1 异常处理 异常处理 ...
- C++ Primer 学习笔记_95_用于大型程序的工具 --多重继承与虚继承
用于大型程序的工具 --多重继承与虚继承 引言: 大多数应用程序使用单个基类的公用继承,可是,在某些情况下,单继承是不够用的,由于可能无法为问题域建模,或者会对模型带来不必要的复杂性. 在这些情况下, ...
- C++ Primer 学习笔记_88_用于大型程序的工具 --异常处理[续1]
用于大型程序的工具 --异常处理[续1] 四.又一次抛出 有可能单个catch不能全然处理一个异常.在进行了一些校正行动之后,catch可能确定该异常必须由函数调用链中更上层的函数来处理,catch能 ...
- C++ Primer 学习笔记_87_用于大型程序的工具 --异常处理
用于大型程序的工具 --异常处理 引言: C++语言包括的一些特征在问题比較复杂,非个人所能管理时最为实用.如:异常处理.命名空间和多重继承. 相对于小的程序猿团队所能开发的系统需求而言,大规模编程[ ...
- C++ Primer 学习笔记_91_用于大型程序的工具 --命名空间
用于大型程序的工具 --命名空间 引言: 在一个给定作用域中定义的每一个名字在该作用域中必须是唯一的,对庞大.复杂的应用程序而言,这个要求可能难以满足.这样的应用程序的全局作用域中一般有很多名字定义. ...
- 【C++ Primer】用于大型程序的工具
1. 异常处理 异常以类似于将实參传递给函数的方式抛出和捕获.异常可以是可传给非引用实參的随意实參的类型,这意味着必须可以复制该类型的对象. 当抛出一个表达式的时候,被抛出对象的静态编译时类型将决定异 ...
- C++ 用于大型程序的工具
<C++ Primer 4th>读书笔记 相对于小的程序员团队所能开发的系统需求而言,大规模编程对程序设计语言的要求更高.大规模应用程序往往具有下列特殊要求: 1. 更严格的正常运转时间以 ...
- C/C++基础----用于大型程序的工具(异常处理,命名空间,多重继承)
独立开发的子系统间协同处理错误的能力 使用各种库(可能包含独立开发的库进行协同开发的能力) 对比复杂的应用概念建模的能力 异常处理 异常将问题的检测和解决过程分离开 当执行一个throw之后,程序控制 ...
- C++ Primer 5th 第1章 开始
*****代码在Ubuntu g++ 5.31 / clang++ 3.8(C++11)下编写调试***** 每个C++程序必须有一个main( )函数,main( )函数的返回值也必须是int类型, ...
随机推荐
- Ubuntu 14.04(64bit)使用indicator-sysmonitor显示系统运行状态
原帖位置:http://tieba.baidu.com/p/3005287033 在使用ubutu时,如果可以查看当前系统使用情况,如CPU,内存,网速等是非常爽的,今天就讲一下一个系统运行状态显示软 ...
- Android 去掉标题全屏显示
自己测试时出现无法实现去掉标题和全屏功能.最后发现只要public class SocketActivity extends Activity {} 而不能用ActionBarActivity. 先介 ...
- log4j2分析总结(一)
现在公司用log4j2 进行日志记录,我也看了相关的资料,现在进行记录学习总结下 整体结构 Appenders里设置日志的输出方式.级别和格式 Loggers里设置全局的级别和绑定appenders里 ...
- delphi adoquery的post和UpdateBatch
delphi adoquery的post和UpdateBatch Post是确认当前的修改,而UpdateBatch是把已经确认但是没有存盘的数据写入数据库当ADOQuery的CursorType是c ...
- Java并发知识点总结
前言:Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.同时,如果想要提升自己的技术,Java并发知识必不可少,这里简单整理了一些相关内容,希望可以起到抛砖引玉的作用 ...
- DispatcherServlet的url mapping为“/”时,对根路径访问的处理
背景 众所周知,Tomcat的Default Servlet的servlet-mapping为 <servlet-mapping> <servlet-name>default& ...
- 【版本管理】git本地操作
1.初始化一个Git仓库,使用git init命令. 2.添加文件到Git仓库,分两步: • 第一步,使用命令git add 文件名,注意,可反复多次使用,添加多个文件: • 第二步,使用命令git ...
- UFLDL学习笔记 ---- 主成分分析与白化
主成分分析(PCA)是用来提升无监督特征学习速度的数据降维算法.看过下文大致可以知道,PCA本质是对角化协方差矩阵,目的是让维度之间的相关性最小(降噪),保留下来的维度能量最大(去冗余),PCA在图像 ...
- 一条慢SQL引发的血案
直接切入正题吧: 通常来说,我们看到的慢查询一般还不致于导致挂站,顶多就是应用响应变慢不过这个恰好今天被我撞见了,一个慢查询把整个网站搞挂了先看看这个SQL张撒样子: # Query_time: 70 ...
- Spring、MyBatis和SpringMVC整合的jar包下载
spring mvc的jar包下载:http://repo.springsource.org/libs-release-local/org/springframework/spring/我下载的5.0 ...