本书结合C++程序,简要介绍了汇编语言,并以栈和队列为主线,逐步深入面向对象的概念。本书从面向过程转向面向对象的编程开始,接着引入类、内联、线程、异常、虚函数、运算符重载、移动语义等概念实现栈和队列,然后基于继承和聚合等概念通过双栈模拟队列,最后引入类模板、类型转换、类型推导等概念实现栈和队列,深入细致地介绍了ISO/IEC 14882:2017标准的全部语法。
为了培养学生面向对象的建模能力,书中按照面向对象的分析与设计步骤,完整展示了骰子游戏的建模过程,并用C++进行了面向对象的程序设计。全书通过挖掘C++概念的应用背景,提供了可供运行的有趣实例和习题。
1.作者为华中科技大学C++课程组组长
2.全书内容便于读者自学
3.注重实用性和系统性,内容循序渐进、深入浅出,以常见易懂的栈和队列为主线,逐步介绍面向对象的思想和概念,揭示面向对象思想的深刻内涵,并给出了应用相关概念的完整程序实例
4.为了使读者能够掌握面向对象的分析、设计与编程方法,本书还完整地展示了骰子游戏的面向对象建模及设计过程,并用C++语言进行了面向对象的程序设计
5.本书给出了丰富的例题和习题,最后一章习题可用于课程设计,能同时提高读者的数学建模能力,以及面向对象的建模能力
6.本书推荐使用Microsoft Visual Studio 2019编译环境
马光志,湖北钟祥人,博士,副教授。先后在美国North Illinois University、Kennesaw State University培训及访问。主要研究方向为人工智能、图像处理、深度学习,曾在国际期刊发表SCI论文20篇、国际会议发表论文10篇。主持与参加了近30个研究开发项目,包括国家自然科学基金、省自然科学基金、国家863及973、国家重大研发计划、中英国际合作及中加国际合作项目,以及与医学图像、医院信息、卫生监管等相关的多个研究开发项目。曾参加C语言至8086汇编语言编译器的研究与开发项目,出版与C++及汇编语言相关的教材3部。
第1章 C++引论
1.1 计算机的体系结构 1
1.1.1 计算机系统的结构 1
1.1.2 数据与程序的存储方式 3
1.2 进制及其转换和运算 4
1.2.1 计算机采用二进制的原因 5
1.2.2 C++的常用进制及其运算 5
1.3 80X86系列汇编语言 7
1.3.1 汇编语言及C++编译简介 7
1.3.2 汇编指令及C++程序编译 9
1.4 C++的发展历史及特点 12
1.4.1 C++的发展历史 12
1.4.2 C++的特点 12
1.5 语法图与程序流程图 13
1.5.1 C++的语法图 13
1.5.2 程序流程图 15
1.6 编译环境的安装与使用 16
1.6.1 编译过程及编译环境 16
1.6.2 Microsoft Visual Studio 2019的安装 17
练习题 22
第2章 类型、常量及变量
2.1 C++的单词 23
2.1.1 C++的字符集 23
2.1.2 C++的关键字 24
2.2 预定义类型及值域和常量 25
2.2.1 预定义类型及其数值转换 25
2.2.2 强制类型转换及类型值域 26
2.2.3 预定义类型及相关常量 28
2.3 变量及其类型解析 31
2.3.1 变量的说明和定义 31
2.3.2 指针及其类型理解 34
2.3.3 有址引用变量 40
2.3.4 无址引用变量 45
2.3.5 元素、下标及数组 47
2.4 运算符及表达式 49
2.4.1 位运算与等号运算 49
2.4.2 指针运算及其结合方向 50
2.4.3 关系运算及结果转换 51
2.5 结构与联合 52
2.5.1 结构体 52
2.5.2 联合体 54
练习题 56
第3章 语句、函数及程序设计
3.1 C++的语句 58
3.1.1 简单语句 58
3.1.2 转移语句 59
3.1.3 分支语句 60
3.1.4 循环语句 63
3.1.5 break和continue语句 67
3.1.6 asm和static_assert语句 68
3.2 C++的函数 68
3.2.1 函数说明与定义 69
3.2.2 头文件与说明 70
3.2.3 函数的参数说明 72
3.2.4 函数重载 74
3.2.5 inline及constexpr函数 75
3.2.6 线程互斥及线程本地变量 77
3.3 作用域 79
3.3.1 全局作用域与模块作用域 79
3.3.2 局部作用域与块作用域 81
3.4 生命期 82
3.5 程序设计实例 84
3.5.1 栈编程实例 84
3.5.2 队列编程实例 86
3.5.3 有限自动机编程实例 87
练习题 90
第4章 C++的类
4.1 类的声明及定义 92
4.1.1 面向对象的基本概念 92
4.1.2 类及对象定义的实例 93
4.2 成员访问权限及突破方法 97
4.2.1 成员的访问权限 97
4.2.2 突破成员的访问权限 98
4.3 内联、匿名类及位段 99
4.3.1 函数成员的内联 99
4.3.2 无对象的匿名联合 101
4.3.3 局部类及位段成员 102
4.4 new和delete运算符 103
4.4.1 简单类型及单个对象内存管理 103
4.4.2 复杂类型及对象数组内存管理 105
4.5 隐含参数this 107
4.6 对象的构造与析构 109
4.6.1 构造函数及对象初始化 109
4.6.2 成员默认值及构造与析构 110
4.7 类及对象的内存布局 112
练习题 116
第5章 成员及成员指针
5.1 实例成员指针 117
5.1.1 实例成员指针的用法 117
5.1.2 实例成员指针的限制 118
5.2 const、volatile和mutable 119
5.2.1 const和volatile的用法 119
5.2.2 mutable实例数据成员 123
5.3 静态数据成员 124
5.3.1 静态数据成员的用法 124
5.3.2 静态数据成员的限制 126
5.4 静态函数成员 128
5.4.1 静态函数成员的访问 128
5.4.2 静态函数成员的限制 129
5.5 静态成员指针 130
5.5.1 静态成员指针的用法 130
5.5.2 多种指针的混合用法 131
5.6 联合的成员指针 132
练习题 133
第6章 继承与构造
6.1 单继承类 136
6.2 继承方式 138
6.2.1 继承后成员的访问权限 138
6.2.2 访问权限的修改 141
6.3 成员访问 142
6.4 构造与析构 143
6.4.1 对象构造的执行顺序 143
6.4.2 new、delete引起的构造与析构 144
6.5 父类和子类 145
6.5.1 父类及其函数调用 145
6.5.2 友元和派生类函数中的父子类
关系 147
6.6 派生类的内存布局 148
练习题 149
第7章 可访问性
7.1 作用域 152
7.1.1 面向对象的作用域 152
7.1.2 面向过程的作用域 155
7.2 名字空间 156
7.2.1 名字空间的基本用法 156
7.2.2 使用名字空间的注意事项 158
7.3 成员友元 160
7.3.1 成员友元的一般用法 161
7.3.2 互为依赖的类的友元 162
7.4 普通友元及其注意事项 163
7.4.1 普通友元的一般用法 163
7.4.2 友元使用的注意事项 165
7.5 覆盖与隐藏 167
7.5.1 覆盖与隐藏的用法 167
7.5.2 使用using避免成员覆盖 169
练习题 170
第8章 多态与虚函数
8.1 虚函数 174
8.1.1 虚函数的声明及定义 174
8.1.2 虚函数的重载及内联 176
8.2 虚析构函数 179
8.3 类的引用 180
8.3.1 类的引用变量及其析构 181
8.3.2 类的引用参数及其析构 183
8.4 抽象类 186
8.4.1 抽象类的定义及用法 186
8.4.2 抽象类的应用实例 187
8.5 虚函数友元与晚期绑定 189
8.5.1 虚函数作为友元 190
8.5.2 虚函数的晚期绑定 191
8.6 有虚函数时的内存布局 192
8.6.1 基类有虚函数时的内存布局 192
8.6.2 基类无虚函数时的内存布局 193
练习题 194
第9章 多继承与虚基类
9.1 多继承类 196
9.1.1 无多继承的替代方案 196
9.1.2 多继承存在的问题 197
9.2 虚基类 198
9.3 派生类成员 200
9.3.1 无虚基类时的成员同名 200
9.3.2 有虚基类时的成员同名 201
9.4 单重及多重继承的构造与析构 202
9.4.1 单继承的构造与析构 202
9.4.2 多继承的构造与析构 204
9.5 多继承类的内存布局 205
9.5.1 无虚基类时的内存布局 205
9.5.2 有虚基类时的内存布局 207
练习题 209
第10章 异常与断言
10.1 异常处理 212
10.1.1 抛出与捕获 212
10.1.2 异常的传播 213
10.2 捕获顺序 214
10.3 函数的异常接口 216
10.3.1 异常接口声明 216
10.3.2 noexcept接口 217
10.4 异常类型 219
10.5 异常对象的析构 220
10.5.1 通过对象指针析构 220
10.5.2 未完成对象的析构 221
10.6 断言 223
练习题 224
第11章 运算符重载
11.1 运算符概述 225
11.1.1 结果为左值的运算符 225
11.1.2 运算符重载的分类 226
11.1.3 成员与非成员重载 227
11.2 运算符参数 228
11.2.1 自增与自减的重载 228
11.2.2 重载->运算符 230
11.2.3 单双目运算符的重载 231
11.3 赋值与调用 232
11.3.1 赋值运算符的重载 232
11.3.2 构造函数的重载 233
11.3.3 安全的编程方法 235
11.4 强制类型转换 236
11.4.1 单个显式参数构造函数 236
11.4.2 强制类型转换重载函数 237
11.5 重载new和delete 238
11.6 运算符重载实例 240
11.6.1 符号表运算的重载实例 240
11.6.2 栈及队列运算重载实例 241
练习题 244
第12章 类型解析、转换与推导
12.1 隐式与显式类型转换 250
12.1.1 简单类型的隐式转换 250
12.1.2 简单类型的显式转换 252
12.1.3 简单类型的转换结果 253
12.2 cast系列类型转换 256
12.2.1 static_cast——静态转换 256
12.2.2 const_cast——只读转换 257
12.2.3 dynamic_cast——动态转换 260
12.2.4 reinterpret_cast——重释转换 263
12.3 类型转换实例 265
12.3.1 typeid获取类型标识 265
12.3.2 explicit要求显式调用 267
12.3.3 栈的类型转换实例 268
12.4 自动类型推导 270
12.4.1 auto的一般用法 271
12.4.2 auto用于函数和数组 271
12.4.3 表达式类型的提取 272
12.5 Lambda表达式 273
12.5.1 Lambda表达式的声明 273
12.5.2 Lambda表达式的参数 275
12.5.3 准函数Lambda表达式 278
练习题 279
第13章 模板与内存回收
13.1 变量模板及其实例 280
13.1.1 变量模板的定义 280
13.1.2 变量模板的实例化 281
13.2 函数模板 282
13.2.1 函数模板的定义 282
13.2.2 成员函数模板的定义 283
13.2.3 函数模板的参数 284
13.3 函数模板实例化 285
13.3.1 函数模板强制实例化 285
13.3.2 函数模板实例特化 286
13.3.3 涉及指针的模板实例化 287
13.4 类模板 288
13.4.1 类模板的定义 288
13.4.2 派生类类模板的定义 289
13.4.3 多类型参数的类模板 290
13.4.4 省略参数的类模板 290
13.4.5 类模板的友元及Lambda表达式 292
13.5 类模板的实例化及特化 294
13.5.1 类模板的实例化 294
13.5.2 类模板实例特化 294
13.5.3 类模板的部分特化 296
13.5.4 实例化与类型推导 297
13.5.5 类模板及实例成员指针 298
13.5.6 模板分隔符的二义性 299
13.5.7 类模板与泛型 300
13.6 内存回收实例 303
练习题 305
第14章 流及类库
14.1 流类概述 307
14.2 输出流 308
14.3 输入流 311
14.4 文件流 312
14.5 串流处理 314
练习题 315
第15章 面向对象开发实例
15.1 面向对象设计概述 316
15.2 对象的静态模型 317
15.3 面向对象的分析 319
15.4 对象的设计与实现 320
15.5 骰子游戏模型设计实例 322
15.5.1 问题描述 322
15.5.2 对象模型 322
15.5.3 对象设计 324
15.6 游戏模型程序设计 326
练习题 331
参考文献 338