logo资料库

高速上手C++11/14/17.pdf

第1页 / 共68页
第2页 / 共68页
第3页 / 共68页
第4页 / 共68页
第5页 / 共68页
第6页 / 共68页
第7页 / 共68页
第8页 / 共68页
资料共68页,剩余部分请下载后查看
序言
引言
目标读者
本书目的
相关代码
第 1 章 迈向 C++11/14/17
1.1 被弃用的特性
1.2 与 C 的兼容性
进一步阅读的参考文献
第 2 章 语言可用性的强化
2.1 常量
nullptr
constexpr
2.2 变量及其初始化
if/switch 变量声明强化
初始化列表
结构化绑定
2.3 类型推导
auto
decltype
尾返回类型推导
decltype(auto)
2.4 控制流
if constexpr
区间 for 迭代
2.5 模板
外部模板
尖括号 ``>''
类型别名模板
默认模板参数
变长参数模板
折叠表达式
2.6 面向对象
委托构造
继承构造
显式虚函数重载
显式禁用默认函数
强类型枚举
总结
习题
进一步阅读的参考文献
第 3 章 语言运行期的强化
3.1 Lambda 表达式
Lambda 表达式基础
泛型 Lambda
3.2 函数对象包装器
std::function
std::bind/std::placeholder
3.3 右值引用
左值、右值的纯右值、将亡值、右值
右值引用和左值引用
移动语义
完美转发
总结
第 4 章 标准库:容器
4.1 std::array 和 std::forward_list
std::array
std::forward_list
4.2 无序容器
4.3 元组 std::tuple
元组基本操作
运行期索引
元组合并与遍历
总结
第 5 章 标准库:指针
5.1 RAII 与引用计数
5.2 std::shared_ptr
5.3 std::unique_ptr
5.4 std::weak_ptr
总结
进一步阅读的参考资料
第 6 章 标准库:正则表达式
6.1 正则表达式简介
普通字符
特殊字符
限定符
6.2 std::regex 及其相关
总结
进一步阅读的参考资料
第 7 章 标准库:线程与并发
7.1 std::thread
7.2 std::mutex, std::unique_lock
7.3 std::future, std::packaged_task
7.4 std::condition_variable
总结
进一步阅读的参考资料
第 8 章 标准库:文件系统
8.1 文档与链接
8.2 std::filesystem
第 9 章 其他杂项
9.1 新类型
long long int
9.2 noexcept 的修饰和操作
9.3 字面量
原始字符串字面量
自定义字面量
总结
第 10 章 展望:C++20 简介
10.1 主要入选特性
非类型模板参数的 auto
std::variant<>
10.2 未入选特性
Concepts TS
总结
进一步阅读的参考资料
附录 1:进一步阅读的学习材料
附录 2:现代 C++ 的最佳实践
常用工具
代码风格
整体性能
代码安全
可维护性
可移植性
高速上手 C++11/14/17 欧长坤 (hi@changkun.us) 最后更新 2019 年 1 月 31 日- v1.0.1-97-g4a8837e 版权声明 本书系欧长坤著,采用“知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (cc by-nc-sa)”进行许 可。http://creativecommons.org/licenses/by-nc-nd/4.0/ 1
目录 序言 目录 目录 引言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 目标读者 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 本书目的 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 相关代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 第 1 章迈向 C++11/14/17 1.1 被弃用的特性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 与 C 的兼容性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 7 7 8 8 8 9 进一步阅读的参考文献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 第 2 章语言可用性的强化 11 2.1 常量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 nullptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 constexpr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2 变量及其初始化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 if/switch 变量声明强化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 初始化列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 结构化绑定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.3 类型推导 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 auto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 decltype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 尾返回类型推导 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 decltype(auto) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.4 控制流 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 if constexpr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 区间 for 迭代 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.5 模板 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 外部模板 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2
目录 目录 尖括号 “>” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 类型别名模板 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 默认模板参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 变长参数模板 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 折叠表达式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.6 面向对象 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 委托构造 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 继承构造 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 显式虚函数重载 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 显式禁用默认函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 强类型枚举 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 习题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 进一步阅读的参考文献 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 第 3 章语言运行期的强化 32 3.1 Lambda 表达式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Lambda 表达式基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 泛型 Lambda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.2 函数对象包装器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 std::function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 std::bind/std::placeholder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.3 右值引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 左值、右值的纯右值、将亡值、右值 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 右值引用和左值引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 移动语义 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 完美转发 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 第 4 章标准库:容器 42 3
目录 目录 4.1 std::array 和 std::forward_list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 std::array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 std::forward_list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4.2 无序容器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4.3 元组 std::tuple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 元组基本操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 运行期索引 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 元组合并与遍历 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 第 5 章标准库:指针 48 5.1 RAII 与引用计数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 5.2 std::shared_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 5.3 std::unique_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 5.4 std::weak_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 进一步阅读的参考资料 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 第 6 章标准库:正则表达式 53 6.1 正则表达式简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 普通字符 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 特殊字符 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 限定符 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.2 std::regex 及其相关 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 进一步阅读的参考资料 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 第 7 章标准库:线程与并发 56 7.1 std::thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 7.2 std::mutex, std::unique_lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 7.3 std::future, std::packaged_task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4
目录 目录 7.4 std::condition_variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 进一步阅读的参考资料 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 第 8 章标准库:文件系统 60 8.1 文档与链接 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 8.2 std::filesystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 第 9 章其他杂项 61 9.1 新类型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 long long int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 9.2 noexcept 的修饰和操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 9.3 字面量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 原始字符串字面量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 自定义字面量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 第 10 章展望:C++20 简介 64 10.1 主要入选特性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 非类型模板参数的 auto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 std::variant<> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 10.2 未入选特性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Concepts TS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 进一步阅读的参考资料 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 附录 1:进一步阅读的学习材料 附录 2:现代 C++ 的最佳实践 67 67 常用工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 代码风格 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 整体性能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 5
目录 目录 代码安全 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 可维护性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 可移植性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 6
序言 序言 引言 C++ 是一个用户群体相当大的语言。从 C++98 的出现到 C++11 的正式定稿经历了长达〸年多之 久的积累。C++14/17 则是作为对 C++11 的重要补充和优化,所有这些新标准中扩充的特性,给 C++ 这门语言注入了新的活力。那些还在坚持使用传统 C++(本书把 C++98 及其之前的 C++ 特性均称 之为传统 C++)而未接触过 C++11/14/17 的 C++ 程序员在见到诸如 Lambda 表达式这类全新特性 时,甚至会流露出『学的不是同一门语言』的惊叹之情。 C++1x (或现代 C++,本书中均指 C++11/14/17) 为传统 C++ 注入的大量特性使得整个 C++ 变得更加像一门现代化的语言。C++1x 不仅仅增强了 C++ 语言自身的可用性,auto 关键字语义的修 改使得我们更加有信心来操控极度复杂的模板类型。同时还对语言运行期进行了大量的强化,Lambda 表达式的出现让 C++ 具有了『匿名函数』的『闭包』特性,而这一特性几乎在现代的编程语言(诸如 Python/Swift/. . . )中已经司空见惯,右值引用的出现解决了 C++ 长期以来被人诟病的临时对象效率 问题等等。 C++17 则是近三年依赖 C++ 社区一致推进的方向,也指出了现代 C++ 编程的一个重要发展方 向。尽管它的出现并不如 C++11 的分量之重,但它包含了大量小而美的语言与特性(例如结构化绑定), 这些特性的出现再一次修正了我们在 C++ 中的编程范式。 现代 C++ 还为自身的标准库增加了非常多的工具和方法,诸如在语言自身标准的层面上制定了 std ::thread,从而支持了并发编程,在不同平台上不再依赖于系统底层的 API,实现了语言层面的跨平台 支持;std::regex 提供了完整的正则表达式支持等等。C++98 已经被实践证明了是一种非常成功的『范 型』,而 C++1x 的出现,则进一步推动这种范型,让 C++ 成为系统程序设计和库开发更好的语言。 总而言之,我们作为 C++ 的拥护与实践者,始终保持接纳新事物的开放心态,才能更快的推进 C++ 的发展,使得这门古老而又新颖的语言更加充满活力。 目标读者 1. 本书假定读者已经熟悉了传统 C++ ,至少在阅读传统 C++ 代码上不具备任何困难。换句话说, 那些长期使用传统 C++ 进行编码的人、渴望在短时间内迅速了解现代 C++ 特性的人非常适合 阅读本书; 2. 本书一定程度上介绍了一些现代 C++ 的黑魔法,但这些魔法毕竟有限,不适合希望进阶学习现代 C++ 的读者,本书的定位系现代 C++ 的快速上手。当然,希望进阶学习的读者可以使用本书来 回顾并检验自己对 现代 C++ 的熟悉度。 本书目的 本书号称『高速上手』,从内容上对二〸一世纪二〸年代之前产生 C++ 的相关特性做了非常相对全 面的介绍,读者可以自行根据下面的目录选取感兴趣的内容进行学习,快速熟悉需要了解的内容。这些 特性并不需要全部掌握,只需针对自己的使用需求和特定的应用场景,学习、查阅最适合自己的新特性 7
相关代码 即可。 第 1 章迈向 C++11/14/17 同时,本书在介绍这些特性的过程中,尽可能简单明了的介绍了这些特性产生的历史背景和技术需 求,这为理解这些特性、运用这些特性提供了很大的帮助。 此外,笔者希望读者在阅读本书后,能够努力在新项目中直接使用 C++17,并努力将旧项目逐步迁 移到 C++17。也算是笔者为推进现代 C++ 的普及贡献了一些绵薄之力。 相关代码 本书每章中都出现了大量的代码,如果你在跟随本书介绍特性的思路编写自己的代码遇到问题时,不 妨读一读随书附上的源码,你可以在这里中找到书中介绍过的全部的源码,所有代码按章节组织,文件 夹名称为章节序号。 第 1 章迈向 C++11/14/17 编译环境:本书将使用 clang++ 作为唯一使用的编译器,同时总是在代码中使用 -std=c++17 编译标 志。 clang ++ -v Apple LLVM version 9.1.0 (clang -902.0.39.1) Target : x86_64 -apple - darwin17 .5.0 Thread model : posix InstalledDir : / Library / Developer / CommandLineTools /usr/bin 1 2 3 4 5 1.1 被弃用的特性 在学习 C++1x 之前,我们先了解一下从 C++11 开始,被弃用的主要特性: 注意:弃用并非彻底不能用,只是用于暗示程序员这些特性将从未来的标准中消失,应该尽 量避免使用。但是,已弃用的特性依然是标准库的一部分,并且出于兼容性的考虑,大部分 特性其实会『永久』保留。 • 不再允许字符串字面值常量赋值给一个 char *。如果需要用字符串字面值常量赋值和初始化一个 char *,应该使用 const char * 或者 auto。 cpp char *str = "hello world!"; // 将出现弃用警告 • C++98 异常说明、unexpected_handler、set_unexpected() 等相关特性被弃用,应该使用 noexcept。 • auto_ptr 被弃用,应使用 unique_ptr。 • register 关键字被弃用,可以使用但不再具备任何实际含义。 • bool 类型的 ++ 操作被弃用。 • 如果一个类有析构函数,为其生成拷贝构造函数和拷贝赋值运算符的特性被弃用了。 8
分享到:
收藏