C++ Primer 第十七章 用于大型程序的工具

第十七章 用于大型程序的工具

相对于小的程序员团队所能开发的系统需求而言,大规模编程 对程序设计语言的要求更高。大规模应用程序往往具有下列特殊要求:

更严格的正常运转时间以及更健壮的错误检测和错误处理。错误处理经常必须跨越独立开发的多个子系统进行。

能够用各种库(可能包含独立开发的库)构造程序。

能够处理更复杂的应用概念。

 

C++ 中有下列三个特征分别针对这些要求:异常处理、命名空间和多重继承。

 

17.1. 异常处理

C++ 的异常处理中,需要由问题检测部分抛出一个对象给处理代码,通过这个对象的类型和内容,两个部分能够就出现了什么错误进行通信。

 

异常是通过抛出 对象而引发 的。该对象的类型决定应该激活哪个处理代码。被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那个。

 

异常以类似于将实参传递给函数的方式抛出和捕获。 异常可以是可传给非引用形参的任意类型的对象,这意味着必须能够复制该类型的对象。

 

传递数组或函数类型实参的时候,该实参自动转换为一个指针。 被抛出的对象将发生同样的自动转换 ,因此,不存在数组或函数类型的异常 。相反。相反,如果抛出一个数组,被抛出的对象转换为指向数组首元素的指针,类似地,如果抛出一个函数,函数被转换为指向该函数的指针第 7.9 节 。

 

执行 throw 的时候,不会执行跟在 throw 后面的语句,而是将控制从 throw 转移到匹配的 catch ,该 catch 可以是同一函数中局部的 catch ,也可以在直接或间接调用发生异常的函数的另一个函数中。控制从一个地方传到另一地方,这有两个重要含义:

 

1.沿着调用链的函数提早退出。第 17.1.2 节 将讨论函数因异常而退出时会发生什么。

2.一般而言,在处理异常的时候,抛出异常的块中的局部存储不存在了。

 

因为在处理异常的时候会释放局部存储,所以被抛出的对象就不能再局部存储 ,而是用 throw 表达式初始化一个称为异常对象 的特殊对象。异常对象由编译器管理,而且保证驻留在可能被激活的任意 catch 都可以访问的空间。 这个对象由 throw 创建,并被初始化为被抛出的表达式的副本。异常对象将传给对应的 catch ,并且在完全处理了异常之后撤销。

 

异常对象通过复制被抛出表达式的结果创建,该结果必须是可以复制的类型。

异常对象与继承

当抛出一个表达式的时候,被抛出对象的静态编译时类型将决定异常对象的类型。

异常与指针

用抛出表达式抛出静态类型时,比较麻烦的一种情况是,在抛出中对指针解引用。对指针解引用的结果是一个对象,其类型与指针的类型匹配。如果指针指向继承层次中的一种类型,指针所指对象的类型就有可能与指针的类型不同。无论对象的实际类型是什么,异常对象的类型都与指针的静态类型相匹配。如果该指针是一个指向派生类对象的基类类型指针,则那个对象将被分割(第 15.3.1 节 ),只抛出基类部分。

 

如果抛出指针本身,可能会引发比分割对象更严重的问题 。具体而言,抛出指向局部对象的指针总是错误的,其理由与从函数返回指向局部对象的指针是错误的一样(第 7.3.2 节 )抛出指针的时候,必须确定进入处理代码时指针所指向的对象存在。

 

如果抛出指向局部对象的指针,而且处理代码在另一函数中,则执行处理代码时指针所指向的对象将不再存在。即使处理代码在同一函数中,也必须确信指针所指向的对象在 catch 处存在。如果指针指向某个在 catch 之前退出的块中的对象,那么,将在 catch 之前撤销该局部对象。

 

抛出指针通常是个坏主意:抛出指针要求在对应处理代码存在的任意地方存在指针所指向的对象。

 

17.1.2. 栈展开

如果对抛出异常的函数的调用是在 try 块中,则检查与该 try 相关的 catch 子句。如果找到匹配的 catch ,就处理异常;如果找不到匹配的 catch ,调用函数也退出,并且继续在调用这个函数的函数中查找。

这个过程,称之为栈展开(stack unwinding) ,沿嵌套函数调用链继续向上,直到为异常找到一个 catch 子句。只要找到能够处理异常的 catch 子句,就进入该 catch 子句,并在该处理代码中继续执行。当 catch 结束的时候,在紧接在与该 try 块相关的最后一个 catch 子句之后的点继续执行。

为局部对象调用析构函数

栈展开期间,释放局部对象所用的内存并运行类类型局部对象的析构函数。

如果一个块直接分配资源,而且在释放资源之前发生异常,在栈展开期间将不会释放该资源。例如,一个块可以通过调用 new 动态分配内存,如果该块因异常而退出,编译器不会删除该指针,已分配的内在将不会释放。

析构函数应该从不抛出异常

在为某个异常进行栈展开的时候,析构函数如果又抛出自己的未经处理的另一个异常,将会导致调用标准库 terminate 函数。一般而言,terminate 函数将调用 abort 函数,强制从整个程序非正常退出。

 

在实践中,因为析构函数释放资源,所以它不太可能抛出异常。标准库类型都保证它们的析构函数不会引发异常。

异常与构造函数

如果在构造函数对象的时候发生异常,则该对象可能只是部分被构造,它的一些成员可能已经初始化,而另一些成员在异常发生之前还没有初始化。即使对象只是部分被构造了,也要保证将会适当地撤销已构造的成员。

类似地,在初始化数组或其他容器类型的元素的时候,也可能发生异常,同样,也要保证将会适当地撤销已构造的元素。

未捕获的异常终止程序

 

 

C++ Primer系列 第18章 用于大型程序的工具 C++ Primer 用于大型程序的工具 阅读详情

相关推荐

C++primer plus和C++ primer的读书心得

C++两本巨著primer plus和primer太过于经典,以至于读过多次,每次阅读仍然有新的收获,所以将一些零碎的知识点整理在这里,与大家共同进步。 1.i++与++i的效率比较: 前缀效率高,后缀在递增前需要一个副本。 ...

weixin_40548480的博客 3109

C++ PRIMER 第十七章 用于大型程序的工具

第17章 用于大型程序的工具   大规模应用程序往往具有下列特殊要求:更严格的正常运转时间以及更健壮的错误检测和错误处理;能够用各种库构造程序;能够处理更复杂的应用概念   17.1 异常处理   使用异常处理,程序中独立开发的各部分能够就程序执行期间出现的问题相互通信,并处理这些问题,提供异常我们能够将问题的检测和问题的解决分离,这样程序的问题检测部分可以不必了解如何处理问题,异常处理中,...

金色的省略号 149

Android Studio中把llama.cpp编译Android .so

本文介绍了一个在Android Studio中集成llama.cpp的最小Demo实现方案,通过JNI将llama.cpp编译为Android.so库,实现本地加载GGUF模型进行文本生成。文章详细说明了项目结构配置(SDK≥30,NDK≥28)、CMake编译设置、Kotlin-JNI-C++的完整调用链实现,以及模型文件部署方式。该Demo采用每次请求新建上下文的简化设计,包含加载模型、生成文本、资源释放等核心功能,并提供了错误排查建议。项目舍弃了上下文保持等复杂功能以确保稳定性,适合作为端侧大语言模型

Zhang Phil 520

C++ Primer 4 第十七章 用于大型程序的工具

第十七章 用于大型程序的工具 1. 异常处理 异常是通过抛出对象而引发的。该对象的类型决定应该激活哪个处理代码。被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那个. 执行 throw 的时候,不会执行跟在 throw 后面的语句,而是将控制从 throw 转移到匹配的 catch,该 catch 可以是同一函数中局部的 catch,也可以在直接或间接调用发生异常的函数的另一个

我的读书笔记(2011-2013) 561

从零开始:ENSP与VirtualBox的兼容性迷宫与突围指南

本文深入解析eNSP与VirtualBox的兼容性问题,特别是报错40的解决方案。从诊断根源、彻底卸载残留到推荐黄金版本组合,提供了一套完整的实战指南,帮助网络工程师和技术学习者快速解决AR_Base等设备的启动故障,优化虚拟化环境性能。

weixin_29284885的博客 476

Unity中USD场景导入与工业级协作实战指南

USD(Universal Scene Description)是一种面向复杂三维场景的结构化数据模型,其核心在于分层描述、变体管理与非破坏性组合,本质是支持多团队并行协作的场景协议。它不同于传统模型格式,强调运行时可编辑性与版本可控性,技术价值体现在跨软件资产一致性、零拷贝动态叠加及内存中实时合成。典型应用场景包括建筑BIM实时漫游、汽车多配置仿真、影视级灯光材质协同等工业管线。在Unity中,USD已深度集成于URP/HDRP管线,通过原生USD Importer、Runtime与Exporter三组件

weixin_32073537的博客 301

[2018年6月12号]C++ primer 课后练习 第十七章 标准库的特殊设施 第十八章用于大型程序的工具

17.3717.38 ifstream is("test_2.txt"); char c[200]; while (!is.eof()) { is.getline(c, 200,'\n'); cout.write(c, is.gcount()); }一开始的版本没有设置delim,发现getline无法自动前进到下一行,折腾了好...

不积跬步无以至千里 322

弹簧管压力表设计报告

精密机械课程设计 弹簧管压力表设计报告 2020年5月1日 目 录 第一章 设计任务概述... 3 1.1 课程设计目的... 3 1.2 设计任务... 3 1.3 技术指标... 3 第二章 压力表概述... 4 2.1 机械式压力表的组成部分... 4 2.2 工作原理... 4 第三章 压力表设计... 5 3.1 弹簧管参数设计... 5 3.2 曲柄滑块机构设计... ...

weixin_42163746的博客 6452

《C++ Primer》学习笔记/习题答案 总目录

文章目录前言专栏C++学习笔记目录第一章 - 快速入门第二章 - 变量和基本类型第三章 - 标准库类型第四章 - 数组和指针第五章 - 表达式第六章 - 语句第七章 - 函数第八章 - 标准 IO 库第九章 - 顺序容器第十章 - 关联容器第十一章 - 泛型算法第十二章 - 类第十三章 - 复制控制第十四章 - 重载操作符与转换第十五章 - 面向对象编程第十六章 - 模板和泛型编程第十七章 - 用...

种树最好的时间是10年前,其次是现在!!! 4万+

AIGC大模型应用教学平台

该平台采用最新的AI推理加速芯片,提供30Tops算力和32GB存储,能够运行常见的大语言模型如ChatGLM2、Llama2、Baicuan、Mistral等,也可以运行文生图扩散模型Stable Diffusion,提供大模型微调、量化、转换和加速推理服务。在此基础上,平台还提供常见的生成式AI应用,包括AIGC知识抽取增强(RAG)、AIGC绘画、AIGC会话聊天、数字虚拟人等应用,以便学生能够掌握最新的生成式AI模型微调、提示工程和智能体应用技能。

中智讯的博客 1208

【外挂编程】外挂编程技术揭秘(二)

引言: 经过上一篇文章大家可能对外挂有了一个初步的认识,之前的内容比较简单,应该大家很容易掌握。我写作过程中我发现三个篇幅可能写不完,后续还可能要多加几个篇幅,这篇我们就先以内存挂为主吧。话不多说了,让我们开始吧。 文章中代码github地址: https://github.com/Diamonds-ZhaoYu/hz_example 环境要求: 系统:Windows 语言...

c-rain 4034

《C++Primer》第十八章 用于大型程序的工具

第十八章 用于大型程序的工具 异常处理 1. 抛出异常 在C++语言中,我们通过抛出throwing一条表达式来引发raised一个异常。当执行一个throw时,跟在throw后面的语句将不再被执行。相反,程序的控制权从throw转移到与之匹配的catch模块。 throw类似于return,其后面的代码不会再被执行。 1.1 栈展开 如果对抛出异常的函数的调用语句位于一个try语句内,则检查...

TOMACAT的博客 593

RV1126笔记二十七:MetaRTC6移植

MetaRTC6移植

6038

c++ primer 第十八章用于大型程序的工具

c++ primer 第十八章用于大型程序的工具18.1 异常处理18.1.1 抛出异常18.1.2 捕获异常18.1.3 函数try语句块与构造函数18.1.4 noexcept异常说明18.1.5 异常类层次18.2 命名空间18.2.1 命名空间定义18.2.2 使用命名空间成员18.2.3 类、命名空间和作用域18.2.4 重载与命名空间18.3 多重继承与虚继承18.3.1 多重继承18...

无所知的博客 671

【无人机编队】基于matlab虚拟leader无人机编队仿真【含Matlab源码 3279期】

虚拟leader无人机编队仿真 完整代码,包运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 837

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

GetQzonehistory:把十年QQ空间历史说说完整导出,Excel和网页一次拿全

GetQzonehistory 是一个本地运行的 Python 小工具,用来把你 QQ 空间发过的历史说说完整抓取下来,导出成 Excel 表格和一个还原空间样式的网页文件,长期存在自己的硬盘里。适合说说发得多、想把这些旧记录完整存档的人。 ## 先说结果:跑完之后你会得到什么 程序跑完后会自动打开 `resource/result/你的QQ号/` 这个文件夹,里面是一套完整的东西: | 产

gitblog_00301的博客 631

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Node-RED 数据处理实战手册:JSON、XML、CSV 的互转与排错

Node-RED 的数据处理,主要靠核心解析器里的一组节点完成:JSON、XML、CSV(还有 HTML、YAML),它们能把 msg 里的字符串、对象和表格数据互相转换。这篇文章不按"技巧清单"罗列,而是跟着一条数据在流程里走完全程:怎么从字符串变成对象,怎么在 XML 和 CSV 之间互转,字段对不上或坏消息出现时怎么办,最后再看怎么提速。 ## 数据入口:三步把 JSON 字符串解析成对象

gitblog_00964的博客 1058

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C++ Primer 第五版 学习总结(十八)第18章 用于大型程序的工具

命名空间的定义包含两部分:关键字namespace和随后的命名空间名字。在命名空间名字后面是一系列由花括号包围的声明和定义。能出现在全局作用域中的声明就也能出现在命名空间中。命名空间作用域后面不需要分号结束。和其他名字一样,命名空间的名字也必须在定义它的作用域内保持唯一。命名空间可以定义在全局作用域内,也可以定义在其他命名空间中,但是不能定义在函数或类的内部。每个命名空间都是一个作用域,不同命名空间内可以有相同名字的成员。

cf18862344377的博客 797

《C++ Primer 4 Answer Book》 整理[16]——第17章 用于大型程序的工具

第17章   用于大型程序的工具         【127】17.1下面的throw语句中,异常对象的类型是什么?         a)range_errorr(“error”); throw r;         b)exception*p=&r; throw *p;         答:a)异常对象r的类型是range_error                   b)被抛出的异常

我的读书笔记(2011-2013) 653

C++ Primer 18 用于大型程序的工具

C++ Primer 用于大型程序的工具

yuyuyuj1e的博客 481

快速上手Cpp-Primer-5th-Exercises:新手必备的C++练习指南 [特殊字符]

想要系统学习C++编程语言,但面对《C++ Primer》这本经典教材的练习题感到无从下手?别担心!Cpp-Primer-5th-Exercises项目为你提供了完整的练习解答,帮助你快速掌握C++编程的核心概念和技巧。这份终极指南将带你深入了解这个宝贵的C++学习资源,让你在编程学习道路上事半功倍! ## 📚 项目简介:你的C++学习好帮手 Cpp-Primer-5th-Exercises

gitblog_01075的博客 1074

掌握C++模板编程:Cpp-Primer-5th-Exercises第16章实战指南

C++模板编程是C++ Primer第5版第16章的核心内容,也是提升C++编程能力的关键技能。通过Cpp-Primer-5th-Exercises项目中的实战练习,你将系统掌握模板类、函数模板、模板特化等核心概念,轻松应对复杂的泛型编程挑战。 ## 为什么模板编程是C++开发者的必备技能 🚀 模板是C++实现泛型编程的基础,它允许你编写与类型无关的代码,大幅提高代码复用性和灵活性。在标准库

gitblog_00320的博客 936

《C++ Primer》导学系列:第 18 章 - 用于大型程序的工具

掌握了异常处理的基本概念和使用方法,包括throwtry和catch关键字的用法。理解了栈展开和资源管理的机制,确保在异常情况下资源能够被正确释放。学会了定义和使用自定义异常类,能够提供自定义的错误信息。熟悉了函数try语句块的使用方法,能够在构造函数中处理异常。理解了noexcept说明符的作用及其在函数、指针和虚函数中的应用。熟悉了标准库中的异常类层次结构,了解各种常见的标准异常类。命名空间通过关键字namespace引入,用于定义一个作用域,其中可以包含变量、函数、类等声明。

iShare_Carlos的博客 1634

C++Primer-课后习题第十七章

本文答案,部分参考于C++ Primer 习题集 前面章节的习题答案 第一章 第二章 第三章 第四章 第五章 第六章 第七章 第八章 第九章 第十章 第十一章 第十二章 第十三章 第十四章 第十五章 第十六章 配套的学习资料 https://www.jianguoyun.com/p/DTK5uJgQldv8CBjKv80D 17.1 tuple<int,int,int> ti{10,20,30}; 17.2 tuple<string, vector<string>, pair

Huangpengyu123的博客 594

C++Primer第五版 习题答案 第十八章 用于大型程序的工具(Tools for Large Programs)

练习18.1 在下列 throw 语句中异常对象的类型是什么? (a) range_error r("error"); throw r; (b) exception *p = &r; throw *p; (a)range_error; (b)exception。 throw p,此时抛出的为指向局部对象的指针,我们几乎可以肯定这是一种错误行为。 练习18.2 当在指定的位置发生...

shamozhizhoutx的博客 1764

TeamAI 自动同步揭秘:AI 会话如何静默获取团队最新资源的完整指南

TeamAI 是一款开源的 AI 团队资源管理 CLI 工具(teamai-cli),它的自动同步机制可以让 Claude Code、Codex、Cursor 等 AI 助手在**每次会话启动时静默拉取团队最新的技能、规则与知识**,全程无需人工干预。本文带你彻底搞懂这套机制背后的原理。✨ ## 什么是 TeamAI 自动同步? 想象这样一个场景:管理员更新了团队的编码规则,昨天还有效的技能今

gitblog_01132的博客 993
上一篇: C++ Primer 第五版 读书笔记 第二章
techmonkey
博客等级 码龄14年 0粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值