第Ⅰ部分 专业的C+简介 2
第1章 C++和标准库速成 2
1.1 C+++基础知识 2
1.1.1 小程序“hello world” 3
1.1.2 名称空间 5
1.1.3 字面量 6
1.1.4 变量 7
1.1.5 运算符 8
1.1.6 类型 10
1.1.7 条件语句 12
1.1.8 逻辑比较运算符 14
1.1.9 函数 15
1.1.10 C风格的数组 16
1.1.11 std::array 17
1.1.12 std::vector 17
1.1.13 结构化绑定 18
1.1.14 循环 18
1.1.15 初始化列表 19
1.1.16 这些都是基础 19
1.2 深入研究C+++ 20
1.2.1 C++++中的字符串 20
1.2.2 指针和动态内存 20
1.2.3 const的多种用法 24
1.2.4 引用 24
1.2.5 异常 25
1.2.6 类型推断 26
1.3 作为面向对象语言的C+++ 27
1.3.1 定义类 27
1.3.2 使用类 29
1.4 统一初始化 29
1.5 标准库 31
1.6 第一个有用的C+++程序 31
1.6.1 雇员记录系统 32
1.6.2 Employee类 32
1.6.3 Database类 34
1.6.4 用户界面 36
1.6.5 评估程序 38
1.7 本章小结 38
第2章 使用string和string_view 39
2.1 动态字符串 39
2.1.1 C风格的字符串 39
2.1.2 字符串字面量 41
2.1.3 C++++std::string类 42
2.1.4 std::string_view类 46
2.1.5 非标准字符串 47
2.2 本章小结 47
第3章 编码风格 48
3.1 良好外观的重要性 48
3.1.1 事先考虑 48
3.1.2 良好风格的元素 49
3.2 为代码编写文档 49
3.2.1 使用注释的原因 49
3.2.2 注释的风格 52
3.3 分解 55
3.3.1 通过重构分解 56
3.3.2 通过设计来分解 56
3.3.3 本书中的分解 56
3.4 命名 56
3.4.1 选择恰当的名称 57
3.4.2 命名约定 57
3.5 使用具有风格的语言特性 59
3.5.1 使用常量 59
3.5.2 使用引用代替指针 59
3.5.3 使用自定义异常 59
3.6 格式 60
3.6.1 关于大括号对齐的争论 60
3.6.2 关于空格和圆括号的争论 61
3.6.3 空格和制表符 61
3.7 风格的挑战 61
3.8 本章小结 62
第Ⅱ部分 专业的C+软件设计 64
第4章 设计专业的C++程序 64
4.1 程序设计概述 64
4.2 程序设计的重要性 65
4.3 C+++设计的特点 66
4.4 C+++设计的两个原则 67
4.4.1 抽象 67
4.4.2 重用 68
4.5 重用代码 69
4.5.1 关于术语的说明 69
4.5.2 决定是否重用代码 70
4.5.3 重用代码的策略 71
4.5.4 绑定第三方应用程序 74
4.5.5 开放源代码库 75
4.5.6 C++++标准库 76
4.6 设计一个国际象棋程序 76
4.6.1 需求 76
4.6.2 设计步骤 77
4.7 本章小结 80
第5章 面向对象设计 82
5.1 过程化的思考方式 82
5.2 面向对象思想 83
5.2.1 类 83
5.2.2 组件 83
5.2.3 属性 83
5.2.4 行为 84
5.2.5 综合考虑 84
5.3 生活在对象世界里 85
5.3.1 过度使用对象 85
5.3.2 过于通用的对象 85
5.4 对象之间的关系 86
5.4.1 “有一个”关系 86
5.4.2 “是一个”关系(继承) 87
5.4.3 “有一个”与“是一个”的区别 88
5.4.4 not-a关系 90
5.4.5 层次结构 91
5.4.6 多重继承 91
5.4.7 混入类 92
5.5 抽象 93
5.5.1 接口与实现 93
5.5.2 决定公开的接口 93
5.5.3 设计成功的抽象 94
5.6 本章小结 95
第6章 设计可重用代码 96
6.1 重用哲学 96
6.2 如何设计可重用代码 97
6.2.1 使用抽象 97
6.2.2 构建理想的重用代码 98
6.2.3 设计有用的接口 102
6.2.4 SOLID原则 106
6.3 本章小结 106
第Ⅲ部分 专业的C+编码方法 108
第7章 内存管理 108
7.1 使用动态内存 108
7.1.1 如何描绘内存 109
7.1.2 分配和释放 110
7.1.3 数组 111
7.1.4 使用指针 116
7.2 数组-指针的对偶性 117
7.2.1 数组就是指针 117
7.2.2 并非所有指针都是数组 119
7.3 低级内存操作 119
7.3.1 指针运算 119
7.3.2 自定义内存管理 120
7.3.3 垃圾回收 120
7.3.4 对象池 121
7.4 智能指针 121
7.4.1 unique_ptr 122
7.4.2 shared_ptr 124
7.4.3 weak_ptr 125
7.4.4 移动语义 126
7.4.5 enable_shared_from_this 127
7.4.6 旧的、过时的/取消的auto_ptr 127
7.5 常见的内存陷阱 127
7.5.1 分配不足的字符串 127
7.5.2 访问内存越界 128
7.5.3 内存泄漏 128
7.5.4 双重删除和无效指针 131
7.6 本章小结 131
第8章 熟悉类和对象 132
8.1 电子表格示例介绍 132
8.2 编写类 133
8.2.1 类定义 133
8.2.2 定义方法 135
8.2.3 使用对象 137
8.3 对象的生命周期 138
8.3.1 创建对象 138
8.3.2 销毁对象 149
8.3.3 对象赋值 149
8.3.4 编译器生成的复制构造函数和复制赋值运算符 151
8.3.5 复制和赋值的区别 151
8.4 本章小结 153
第9章 精通类与对象 154
9.1 友元 154
9.2 对象的动态内存分配 155
9.2.1 Spreadsheet类 155
9.2.2 使用析构函数释放内存 157
9.2.3 处理复制和赋值 158
9.2.4 使用移动语义处理移动 162
9.2.5 零规则 167
9.3 与方法有关的更多内容 167
9.3.1 静态方法 167
9.3.2 const方法 168
9.3.3 方法重载 169
9.3.4 内联方法 170
9.3.5 默认参数 171
9.4 不同的数据成员类型 172
9.4.1 静态数据成员 172
9.4.2 静态常量数据成员 173
9.4.3 引用数据成员 174
9.4.4 常量引用数据成员 175
9.5 嵌套类 175
9.6 类内的枚举类型 176
9.7 运算符重载 177
9.7.1 示例:为SpreadsheetCell实现加法 177
9.7.2 重载算术运算符 179
9.7.3 重载比较运算符 181
9.7.4 创建具有运算符重载的类型 181
9.8 创建稳定的接口 182
9.9 本章小结 184
第10章 揭秘继承技术 185
10.1 使用继承构建类 185
10.1.1 扩展类 186
10.1.2 重写方法 188
10.2 使用继承重用代码 194
10.2.1 WeatherPrediction类 194
10.2.2 在派生类中添加功能 195
10.2.3 在派生类中替换功能 196
10.3 利用父类 196
10.3.1 父类构造函数 196
10.3.2 父类的析构函数 197
10.3.3 使用父类方法 198
10.3.4 向上转型和向下转型 200
10.4 继承与多态性 201
10.4.1 回到电子表格 201
10.4.2 设计多态性的电子表格单元格 201
10.4.3 SpreadsbeetCell基类 202
10.4.4 独立的派生类 203
10.4.5 利用多态性 204
10.4.6 考虑将来 205
10.5 多重继承 206
10.5.1 从多个类继承 206
10.5.2 名称冲突和歧义基类 207
10.6 有趣而晦涩的继承问题 209
10.6.1 修改重写方法的特征 209
10.6.2 继承的构造函数 211
10.6.3 重写方法时的特殊情况 214
10.6.4 派生类中的复制构造函数和赋值运算符 219
10.6.5 运行时类型工具 220
10.6.6 非public继承 221
10.6.7 虚基类 221
10.7 本章小结 222
第11章 理解灵活而奇特的C++ 223
11.1 引用 223
11.1.1 引用变量 224
11.1.2 引用数据成员 225
11.1.3 引用参数 225
11.1.4 将引用作为返回值 226
11.1.5 右值引用 226
11.1.6 使用引用还是指针 227
11.2 关键字的疑问 229
11.2.1 const关键字 229
11.2.2 static关键字 232
11.2.3 非局部变量的初始化顺序 235
11.2.4 非局部变量的销毁顺序 235
11.3 类型和类型转换 235
11.3.1 类型别名 235
11.3.2 函数指针的类型别名 236
11.3.3 方法和数据成员的指针的类型别名 238
11.3.4 typedef 238
11.3.5 类型转换 239
11.4 作用域解析 242
11.5 特性 243
11.5.1 [[noreturn]]特性 243
11.5.2 [[deprecated]]特性 244
11.5.3 [[fallthrough]]特性 244
11.5.4 [[nodiscard]]特性 244
11.5.5 [[maybe_unused]]特性 244
11.5.6 供应商专用特性 245
11.6 用户定义的字面量 245
11.7 头文件 246
11.8 C的实用工具 247
11.8.1 变长参数列表 247
11.8.2 预处理器宏 249
11.9 本章小结 250
第12章 利用模板编写泛型代码 251
12.1 模板概述 252
12.2 类模板 252
12.2.1 编写类模板 252
12.2.2 尖括号 258
12.2.3 编译器处理模板的原理 258
12.2.4 将模板代码分布在多个文件中 258
12.2.5 模板参数 260
12.2.6 方法模板 263
12.2.7 类模板的特例化 266
12.2.8 从类模板派生 267
12.2.9 继承还是特例化 268
12.2.10 模板别名 268
12.3 函数模板 269
12.3.1 函数模板的特例化 270
12.3.2 函数模板的重载 271
12.3.3 类模板的友元函数模板 271
12.3.4 对模板参数推导的更多介绍 272
12.3.5 函数模板的返回类型 272
12.4 可变模板 274
12.5 本章小结 274
第13章 C++ I/O揭秘 275
13.1 使用流 275
13.1.1 流的含义 276
13.1.2 流的来源和目的地 276
13.1.3 流式输出 277
13.1.4 流式输入 280
13.1.5 对象的输入输出 285
13.2 字符串流 286
13.3 文件流 287
13.3.1 文本模式与二进制模式 287
13.3.2 通过seek()和tell()在文件中转移 288
13.3.3 将流链接在一起 289
13.4 双向I/O 290
13.5 本章小结 291
第14章 错误处理 292
14.1 错误与异常 292
14.1.1 异常的含义 292
14.1.2 C++++中异常的优点 293
14.1.3 我们的建议 294
14.2 异常机制 294
14.2.1 抛出和捕获异常 295
14.2.2 异常类型 296
14.2.3 按const和引用捕获异常对象 297
14.2.4 抛出并捕获多个异常 297
14.2.5 未捕获的异常 299
14.2.6 noexcept 300
14.2.7 抛出列表(已不赞成使用/已删除) 300
14.3 异常与多态性 301
14.3.1 标准异常体系 301
14.3.2 在类层次结构中捕获异常 302
14.3.3 编写自己的异常类 303
14.3.4 嵌套异常 305
14.4 重新抛出异常 306
14.5 堆栈的释放与清理 307
14.5.1 使用智能指针 308
14.5.2 捕获、清理并重新抛出 309
14.6 常见的错误处理问题 309
14.6.1 内存分配错误 309
14.6.2 构造函数中的错误 311
14.6.3 构造函数的function-try-blocks 312
14.6.4 析构函数中的错误 314
14.7 综合应用 315
14.8 本章小结 318
第15章 C++运算符重载 319
15.1 运算符重载概述 319
15.1.1 重载运算符的原因 320
15.1.2 运算符重载的限制 320
15.1.3 运算符重载的选择 320
15.1.4 不应重载的运算符 322
15.1.5 可重载运算符小结 322
15.1.6 右值引用 324
15.1.7 关系运算符 325
15.2 重载算术运算符 325
15.2.1 重载一元负号和一元正号运算符 325
15.2.2 重载递增和递减运算符 326
15.3 重载按位运算符和二元逻辑运算符 327
15.4 重载插入运算符和提取运算符 327
15.5 重载下标运算符 328
15.5.1 通过operator[]提供只读访问 330
15.5.2 非整数数组索引 330
15.6 重载函数调用运算符 331
15.7 重载解除引用运算符 332
15.7.1 实现operator 333
15.7.2 实现operator-> 333
15.7.3 operator.*和operator->*的含义 334
15.8 编写转换运算符 334
15.8.1 使用显式转换运算符解决多义性问题 335
15.8.2 用于布尔表达式的转换 335
15.9 重载内存分配和内存释放运算符 337
15.9.1 new和delete的工作原理 337
15.9.2 重载operator new和operator delete 338
15.9.3 显式地删除/默认化operator new和operator delete 340
15.9.4 重载带有额外参数的operator new和operator delete 340
15.9.5 重载带有内存大小参数的operator delete 340
15.10 本章小结 341
第16章 C++标准库概述 342
16.1 编码原则 343
16.1.1 使用模板 343
16.1.2 使用运算符重载 343
16.2 C+++标准库概述 343
16.2.1 字符串 343
16.2.2 正则表达式 344
16.2.3 I/O流 344
16.2.4 智能指针 344
16.2.5 异常 344
16.2.6 数学工具 344
16.2.7 时间工具 345
16.2.8 随机数 345
16.2.9 初始化列表 345
16.2.10 pair和tuple 345
16.2.11 optional、variant和any 345
16.2.12 函数对象 346
16.2.13 文件系统 346
16.2.14 多线程 346
16.2.15 类型特质 346
16.2.16 标准整数类型 346
16.2.17 容器 346
16.2.18 算法 351
16.2.19 标准库中还缺什么 358
16.3 本章小结 358
第17章 理解容器与迭代器 359
17.1 容器概述 359
17.1.1 对元素的要求 360
17.1.2 异常和错误检查 361
17.1.3 迭代器 361
17.2 顺序容器 363
17.2.1 vector 363
17.2.2 vector<bool>特化 376
17.2.3 deque 377
17.2.4 list 377
17.2.5 forward_list 380
17.2.6 array 381
17.3 容器适配器 382
17.3.1 queue 382
17.3.2 priority_queue 384
17.3.3 stack 386
17.4 有序关联容器 387
17.4.1 pair工具类 387
17.4.2 map 388
17.4.3 multimap 393
17.4.4 set 396
17.4.5 multiset 397
17.5 无序关联容器/哈希表 397
17.5.1 哈希函数 397
17.5.2 unordered_map 399
17.5.3 unordered_multimap 401
17.5.4 unordered_set/unordered_multiset 402
17.6 其他容器 402
17.6.1 标准C风格数组 402
17.6.2 string 403
17.6.3 流 403
17.6.4 bitset 403
17.7 本章小结 407
第18章 掌握标准库算法 408
18.1 算法概述 408
18.1.1 find()和find_if()算法 409
18.1.2 accumulate()算法 410
18.1.3 在算法中使用移动语义 411
18.2 std::function 411
18.3 lambda表达式 413
18.3.1 语法 413
18.3.2 泛型lambda表达式 415
18.3.3 lambda捕捉表达式 415
18.3.4 将lambda表达式用作返回类型 415
18.3.5 将lambda表达式用作参数 416
18.3.6 标准库算法示例 416
18.4 函数对象 417
18.4.1 算术函数对象 417
18.4.2 比较函数对象 418
18.4.3 逻辑函数对象 419
18.4.4 按位函数对象 419
18.4.5 函数对象适配器 419
18.4.6 std::invoke() 422
18.4.7 编写自己的函数对象 423
18.5 算法详解 423
18.5.1 迭代器 424
18.5.2 非修改序列算法 424
18.5.3 修改序列算法 427
18.5.4 操作算法 433
18.5.5 交换算法 434
18.5.6 分区算法 435
18.5.7 排序算法 436
18.5.8 二叉树搜索算法 436
18.5.9 集合算法 437
18.5.10 最大/最小算法 439
18.5.11 并行算法 440
18.5.12 数值处理算法 440
18.6 算法示例:审核选民登记 442
18.6.1 选民登记审核问题描述 442
18.6.2 audit VoterRolls()函数 442
18.6.3 getDuplicates()函数 443
18.6.4 测试auditVoterRolls()函数 443
18.7 本章小结 444
第19章 字符串的本地化与正则表达式 445
19.1 本地化 445
19.1.1 本地化字符串字面量 445
19.1.2 宽字符 446
19.1.3 非西方字符集 446
19.1.4 转换 447
19.1.5 locale和facet 448
19.2 正则表达式 450
19.2.1 ECMAScript语法 451
19.2.2 regex库 455
19.2.3 regex_match() 456
19.2.4 regex_search() 458
19.2.5 regex_iterator 458
19.2.6 regex_token_iterator 459
19.2.7 regex_replace() 461
19.3 本章小结 462
第20章 其他库工具 463
20.1 ratio库 463
20.2 chrono库 465
20.2.1 持续时间 465
20.2.2 时钟 468
20.2.3 时点 469
20.3 生成随机数 470
20.3.1 随机数引擎 471
20.3.2 随机数引擎适配器 472
20.3.3 预定义的随机数引擎和引擎适配器 472
20.3.4 生成随机数 473
20.3.5 随机数分布 474
20.4 optional 476
20.5 variant 477
20.6 any 478
20.7 元组 479
20.7.1 分解元组 481
20.7.2 串联 481
20.7.3 比较 482
20.7.4 make_from_tuple() 482
20.7.5 apply() 483
20.8 文件系统支持库 483
20.8.1 path 483
20.8.2 directory_entry 484
20.8.3 辅助函数 484
20.8.4 目录迭代 484
20.9 本章小结 485
第Ⅳ部分 掌握C+的高级特性 488
第21章 自定义和扩展标准库 488
21.1 分配器 488
21.2 流适配器 489
21.2.1 输出流迭代器 489
21.2.2 输入流迭代器 490
21.3 迭代器适配器 490
21.3.1 反向迭代器 490
21.3.2 插入迭代器 491
21.3.3 移动迭代器 492
21.4 扩展标准库 493
21.4.1 扩展标准库的原因 493
21.4.2 编写标准库算法 493
21.4.3 编写标准库容器 495
21.5 本章小结 519
第22章 高级模板 520
22.1 深入了解模板参数 520
22.1.1 深入了解模板类型参数 520
22.1.2 template template参数介绍 522
22.1.3 深入了解非类型模板参数 524
22.2 模板类部分特例化 525
22.3 通过重载模拟函数部分特例化 527
22.4 模板递归 528
22.4.1 N维网格:初次尝试 529
22.4.2 真正的N维网格 529
22.5 可变参数模板 531
22.5.1 类型安全的变长参数列表 532
22.5.2 可变数目的混入类 533
22.5.3 折叠表达式 534
22.6 模板元编程 535
22.6.1 编译时阶乘 536
22.6.2 循环展开 536
22.6.3 打印元组 537
22.6.4 类型trait 539
22.6.5 模板元编程结论 545
22.7 本章小结 545
第23章 C++多线程编程 546
23.1 多线程编程概述 547
23.1.1 争用条件 548
23.1.2 撕裂 549
23.1.3 死锁 549
23.1.4 伪共享 550
23.2 线程 550
23.2.1 通过函数指针创建线程 550
23.2.2 通过函数对象创建线程 551
23.2.3 通过lambda创建线程 552
23.2.4 通过成员函数创建线程 553
23.2.5 线程本地存储 553
23.2.6 取消线程 553
23.2.7 从线程获得结果 553
23.2.8 复制和重新抛出异常 554
23.3 原子操作库 555
23.3.1 原子类型示例 556
23.3.2 原子操作 557
23.4 互斥 558
23.4.1 互斥体类 558
23.4.2 锁 560
23.4.3 std::call_once 561
23.4.4 互斥体对象的用法示例 562
23.5 条件变量 565
23.5.1 假唤醒 565
23.5.2 使用条件变量 565
23.6 future 566
23.6.1 std::promise和std::future 567
23.6.2 std::packaged_task 567
23.6.3 std::async 568
23.6.4 异常处理 568
23.6.5 std::shared_future 569
23.7 示例:多线程的Logger类 570
23.8 线程池 573
23.9 线程设计和最佳实践 573
23.10 本章小结 574
第Ⅴ部分 C+软件工程 576
第24章 充分利用软件工程方法 576
24.1 过程的必要性 576
24.2 软件生命周期模型 577
24.2.1 瀑布模型 577
24.2.2 生鱼片模型 578
24.2.3 螺旋类模型 579
24.2.4 敏捷 581
24.3 软件工程方法论 581
24.3.1 UP 581
24.3.2 RUP 582
24.3.3 Scrum 583
24.3.4 极限编程 584
24.3.5 软件分流 587
24.4 构建自己的过程和方法 588
24.4.1 对新思想采取开放态度 588
24.4.2 提出新想法 588
24.4.3 知道什么行得通、什么行不通 588
24.4.4 不要逃避 588
24.5 源代码控制 588
24.6 本章小结 590
第25章 编写高效的C++程序 591
25.1 性能和效率概述 591
25.1.1 提升效率的两种方式 592
25.1.2 两种程序 592
25.1.3 C++++是不是低效的语言 592
25.2 语言层次的效率 592
25.2.1 高效地操纵对象 593
25.2.2 预分配内存 596
25.2.3 使用内联方法和函数 596
25.3 设计层次的效率 596
25.3.1 尽可能多地缓存 596
25.3.2 使用对象池 597
25.4 剖析 599
25.4.1 使用gprof的剖析示例 600
25.4.2 使用Visual C++++ 2017的剖析示例 605
25.5 本章小结 608
第26章 熟练掌握测试技术 609
26.1 质量控制 609
26.1.1 谁负责测试 610
26.1.2 bug的生命周期 610
26.1.3 bug跟踪工具 611
26.2 单元测试 612
26.2.1 单元测试方法 613
26.2.2 单元测试过程 613
26.2.3 实际中的单元测试 616
26.3 高级测试 622
23.3.1 集成测试 622
26.3.2 系统测试 623
26.3.3 回归测试 623
26.4 用于成功测试的建议 624
26.5 本章小结 624
第27章 熟练掌握调试技术 625
27.1 调试的基本定律 625
27.2 bug分类学 626
27.3 避免bug 626
27.4 为bug做好规划 626
27.4.1 错误日志 626
27.4.2 调试跟踪 627
27.4.3 断言 633
27.4.4 崩溃转储 633
27.5 静态断言 634
27.6 调试技术 634
27.6.1 重现bug 635
27.6.2 调试可重复的bug 635
27.6.3 调试不可重现的bug 635
27.6.4 调试退化 636
27.6.5 调试内存问题 636
27.6.6 调试多线程程序 640
27.6.7 调试示例:文章引用 640
27.6.8 从ArticleCitations示例中总结出的教训 648
27.7 本章小结 649
第28章 使用设计技术和框架 650
28.1 容易忘记的语法 651
28.1.1 编写类 651
28.1.2 派生类 652
28.1.3 使用“复制和交换”惯用语法 652
28.1.4 抛出和捕捉异常 653
28.1.5 读取文件 654
28.1.6 写入文件 654
28.1.7 写入模板类 654
28.2 始终存在更好的方法 655
28.2.1 RAII 655
28.2.2 双分派 657
28.2.3 混入类 660
28.3 面向对象的框架 662
28.3.1 使用框架 662
28.3.2 MVC范型 662
28.4 本章小结 663
第29章 应用设计模式 664
29.1 迭代器模式 665
29.2 单例模式 665
29.2.1 日志记录机制 665
29.2.2 实现单例 666
29.2.3 使用单例 668
29.3 抽象工厂模式 668
29.3.1 示例:模拟汽车工厂 669
29.3.2 实现工厂 670
29.3.3 使用工厂 671
29.3.4 工厂的其他用法 672
29.4 代理模式 672
29.4.1 示例:隐藏网络连接问题 673
29.4.2 实现代理 673
29.4.3 使用代理 674
29.5 适配器模式 674
29.5.1 示例:改编Logger类 674
29.5.2 实现适配器 675
29.5.3 使用适配器 675
29.6 装饰器模式 675
29.6.1 示例:在网页中定义样式 676
29.6.2 装饰器的实现 676
29.6.3 使用装饰器 677
29.7 责任链模式 677
29.7.1 示例:事件处理 678
29.7.2 实现责任链 678
29.7.3 没有层次结构的责任链 679
29.8 观察者模式 680
29.8.1 实现观察者 680
29.8.2 实现可观察类 681
29.8.3 使用观察者 681
29.9 本章小结 682
第30章 开发跨平台和跨语言应用程序 683
30.1 跨平台开发 683
30.1.1 架构问题 683
30.1.2 实现问题 686
30.1.3 平台专用功能 686
30.2 跨语言开发 687
30.2.1 混用C和C++++ 687
30.2.2 改变范型 688
30.2.3 链接C代码 690
30.2.4 从C#调用C++++代码 691
30.2.5 在Java中使用JNI调用C++++代码 692
30.2.6 从C++++代码调用脚本 694
30.2.7 从脚本调用C++++代码 694
30.2.8 从C++++调用汇编代码 696
30.3 本章小结 696
附录A C++面试 697
附录B 带注解的参考文献 713
附录C 标准库头文件 721
附录D UML简介 726