猜你喜欢
学习C++20(中文版)

学习C++20(中文版)

书籍作者:保罗·J.戴特尔(Paul ISBN:9787302625438
书籍语言:简体中文 连载状态:全集
电子书格式:pdf,txt,epub,mobi,azw3 下载次数:9536
创建日期:2024-04-09 发布日期:2024-04-09
运行环境:PC/Windows/Linux/Mac/IOS/iPhone/iPad/Kindle/Android/安卓/平板
内容简介

《学习C++20(中文版)》共18章5个附录,讨论了C++20的5大编程模型:程序化编程、函数式编程、面向对象编程、泛型编程和模板元编程。第I部分介绍基础知识,第II部分介绍容器、C++20范围、指针、字符串和文件,第III部分介绍现代面向对象编程和异常,第Ⅳ部分介绍泛型编程、模板、概念和模板元编程,第V部分介绍高级主题,包括模块、并行算法、并发和协程。

《学习C++20(中文版)》适合需要了解C++20新特性的程序员,包括零基础或有经验的C++程序员以及其他想要了解C++的程序员,也适合希望开课教C++20的老师。


作者简介

保罗·J.戴特尔(Paul J. Deitel)毕业于麻省理工学院(MIT),有42年计算机行业的工作经验。他是全球知名的编程语言培训师之一,自1992年以来一直在为软件开发人员讲授专业课程。他与哈维·M.戴特尔(Harvey M. Deitel)博士共同编写了全球畅销的编程教材、专业书籍、视频和互动多媒体电子学习内容。

前言

欢迎阅读《学习C++20(中文版)》。本书旨在为软件开发人员介绍前沿的计算机编程语言,遵循的是ISO C++标准委员会在2020年9月通过的C++20标准(英文版有1834页)。

C++编程语言适合用来构建高性能的关键业务和关键任务计算系统,包括操作系统、实时系统、嵌入式系统、游戏系统、银行系统、空中管制系统以及通信系统等。本书的定位是帮助读者掌握C++语言,所以书中涵盖了C++语言本身(世界上最流行的编程语言之一)及其相关的标准库,对C++20进行了友好的、现代的、范例代码丰富的、面向案例的介绍。在这里,我们将探讨这本书的“灵魂”。

着眼于现代C++

本书专注于“现代C++”,包含了四个最新的C++标准:C++20、C++17、C++14和C++11,并对C++23以及更新的关键特性进行了展望。本书致力于探讨如何以一些新的和改进的方法用C++进行编码。我们采用的是最佳实践,强调当前专业软件开发的“现代C++”惯例,并将重点放在性能、安全性和软件工程这几个主题上。

保持话题性

“勇于传道授业解惑的人,是绝对不会停止进步的。”(约翰·科顿·达纳)

为了掌握“现代C++”的发展动态并改变开发人员用C++来写代码的方式,我们阅读、浏览或观看了最新的文章、研究论文、白皮书、文档以及博客帖子、论坛帖子和视频,数量累计超过6 000。

C++版本

作为开发人员,你可能要按项目要求解决C++遗留代码或使用特定的C++版本。为此,本书中提到了“C++20”这样的提示,以便每次提到某个“现代C++”语言特性时,你就知道它首次出现于C++哪个版本中。这些内容有助于你体会C++的发展历程:通常都是从低级别的细节,逐渐发展到更容易使用的高级别的表达形式。这个趋势有利于缩短开发时间、改善性能、提高安全性和系统可维护性。

目标读者

本书面向以下四类读者。

希望能够有一本内容全面、专业精深的教程可以帮助自己学习最新C++20特性的C++软件开发人员。

需要做C++项目并想学习最新语言特性的非C++软件开发人员。

在大学里学过C++或者在一段时间内因为职业需要用过C++并希望在C++20的背景下更新C++知识的软件开发人员。

计划开发C++20课程的C++职业培训师。

“实时编码”方法和代码下载

本书的核心内容是我们Deitel标志性的实时编码(Live-Code)方法。我们不展示代码片段,而是在数百个完整的、可运行的、具有实时输出的真实C++程序的背景下使用C++。

请阅读“前言”之后的“准备工作”部分,从中了解如何设置Windows、macOS或Linux计算机,以便运行大约由15 000行代码组成的200多个代码示例。所有源代码都可以在以下网站免费下载:

https://github.com/pdeitel/CPlusPlus20ForProgrammers

https://www.deitel.com/books/c-plus-plus-20-for-programmers

https://informit.com/title/9780136905691

为了提供方便,我们以C++源代码(后缀名为.cpp和.h)文件的形式提供本书的例子,供集成开发环境和命令行编译器使用。参见第1章的“试运行”一节(第1.2节),了解如何用我们推荐的三种编译器来编译和运行代码示例。在看书的同时执行每个程序,会有鲜活的学习体验。遇到任何问题,都可以通过[email protected]联系

我们。

三种工业强度的编译器

我们在以下最新版本的平台上测试了所有代码示例。

Windows?平台:Microsoft? Visual Studio?社区版的Visual C++?。

macOS?平台:Apple? Xcode?以及一个Docker?容器中的Clang C++(clang++)。

Linux?平台:GNU编译器集合(GCC)Docker?容器中的GNU? C++(g++)。

写作本书的时候,大多数C++20特性已经由所有三个编译器完全实现,有些由三个编译器中的一个子集实现,有些还没有由任何编译器实现。我们会酌情指出这些差异并在编译器厂商实现剩余的C++20特性时更新我们的数字版的内容。我们还会在本书的GitHub仓库中发布代码更新:

https://github.com/pdeitel/CPlusPlus20ForProgrammers

本书配套网站同时提供对代码和正文的更新:

https://www.deitel.com/books/c-plus-plus-20-for-programmers

https://informit.com/title/9780136905691

本书中文版网站会提供中文版后期勘误:

https://bookzhou.com

编程技巧和C++20关键特性

本书使用多种图标来提醒读者留意软件开发技巧及C++20的模块和概念特征。

这类图标着重强调为正确开发软件而需要注意的架构和设计问题,特别是对于较大型的系统。

这样的最佳实践帮助大家加强程序安全以抵御攻击。

这一类提示给出了使你的程序运行得更快或尽量减少占用内存的窍门。

常见编程错误有助于减少犯同样错误的可能性。

C++核心准则建议(后面有具体说明)。

C++20新的模块特性。

C++20新的概念特性。


“对象自然”方法

第9章开始介绍如何开发自定义的C++20类并在后续章节继续讨论面向对象编程。

1. 何为对象自然

在第9章之前的各章,使用的是一些现有的类,它们能完成很多重要的工作。我们快速创建这些类的对象,并通过数量最少的简单C++语句让它们“大显身手”。这就是我们所称的“对象自然方法”(Objects-Natural Approach)。

C++社区已经创建了大量免费、开源的类库,所以在第9章学习如何创建自己的C++类之前,大多数读者就已经能够执行强大的任务了。这是使用面向对象语言(特别是C++这样成熟的面向对象语言)最吸引人的地方。

2. 免费的类

我们鼓励使用C++生态系统中现有的类,数量大且有价值、免费,它们通常有以下来源:

C++标准库

平台特有的库,如微软的Windows、苹果的macOS或各种Linux版本所提供的库

免费的第三方C++库,通常由开源社区创建

其他开发者,比如你所在组织的开发者

我们鼓励大家查看大量免费的、开源的C++代码实例(可在GitHub等网站上找到),从中找找灵感。

3. Boost项目

Boost提供了168个开源的C++库。它也是最终被纳入C++标准库之新特性的“温床”。一些已被添加到“现代C++”的特性包括多线程、随机数生成、智能指针、元组、正则表达式、文件系统和string_view。以下StackOverflow答案列出了从Boost库演变而来的“现代C++”库和语言特性:

https://stackoverflow.com/a/8852421

4. 对象自然案例学习

第1章主要学习解释对象技术的基本概念和术语。然后,到第9章之前,本书的重点都是创建并使用现有类的对象。在第9章及之后的各章,才会开始创建自定义类。我们的对象自然案例学习如下:

2.7节——创建并使用标准库string类的对象

3.12节——任意大小的整数

4.13节——使用miniz-cpp库读写ZIP文件

5.20节——Lnfylun Lhqtomh Wjtz Qarcv: Qjwazkrplm xzz Xndmwwqhlz(这是我们私钥加密案例学习的加密标题)

6.15节——C++标准库模板类vector

7.10节——C++20 span:连续容器元素的视图

8.19节——读取/分析包含泰坦尼克号灾难数据的CSV文件

8.20节——正则表达式简介

9.22节——用JSON序列化对象

对于对象自然,一个完美的例子是直接使用现有类的对象,如array和vector(第6章),而不需要知道如何编写自定义类,特别是不需要知道如何编写这些类。本书会广泛使用现有C++标准库的功能。

目录

简明目录

第Ⅰ部分 编程基础

第1章 免费、流行的C++编译器 003

第2章 C++编程入门 025

第3章 控制语句(上) 045

第4章 控制语句(下) 077

第5章 函数和函数模板入门 113

第Ⅱ部分 数组、指针和字符串

第6章 数组、向量、范围和函数式编程 171

第7章 现代C++对指针的淡化 211

第8章 string、string_view、文本文件、CSV文件和正则表达式 247

第Ⅲ部分 面向对象程序设计

第9章 自定义类 303

第10章 OOP:继承和运行时多态性 379

第11章 操作符重载、拷贝/移动语义和智能指针 467

第12章 异常和对契约的展望 527

第Ⅳ部分 标准库容器、迭代器和算法

第13章 标准库容器和迭代器 571

第14章 标准库算法和C++20范围/视图 625

第Ⅴ部分 高级编程主题

第15章 模板、C++20“概念”和元编程 703

第16章 C++20模块:大规模开发 797

第17章 并行算法和并发性:高级观点 851

第18章 C++20协程 994

附录A 操作符优先级和分组 969

附录B 字符集 971


详细目录

第Ⅰ部分 编程基础

第1章 免费、流行的C++编译器

1.1 导读 004

1.2 试运行一个C++20应用程序 005

1.2.1 在Windows上用VS 2022社区版编译和运行C++20应用程序 005

1.2.2 在macOS上用Xcode编译和运行C++20应用程序 009

1.2.3 在Linux上用GNU C++运行C++20应用程序 013

1.2.4 在GCC Docker容器中编译和运行C++20应用程序 015

1.2.5 在Docker容器中使用clang++来编译和运行C++20应用程序 016

1.3 摩尔定律、多核处理器和并发编程 018

1.4 面向对象简单回顾 019

1.5 小结 021

第2章 C++编程入门

2.1 导读 026

2.2 第一个C++程序:显示单行文本 026

2.3 修改第一个C++程序 030

2.4 另一个C++程序:整数相加 031

2.5 算术运算 035

2.6 决策:相等性和关系操作符 036

2.7 对象自然案例学习:创建和使用标准库类string的对象 040

2.8 小结 044

第3章 控制语句(上)

3.1 导读 046

3.2 控制结构 046

3.2.1 顺序结构 046

3.2.2 选择语句 047

3.2.3 循环语句 048

3.2.4 控制语句小结 049

3.3 if选择语句 049

3.4 if…else双选语句 050

3.4.1 嵌套if…else语句 051

3.4.2 代码块 052

3.4.3 条件操作符( :) 053

3.5 while循环语句 053

3.6 计数器控制的循环 054

3.6.1 实现计数器控制的循环 054

3.6.2 整数除法和截断 056

3.7 哨兵值控制的循环 056

3.7.1 实现哨兵值控制的循环 057

3.7.2 基础类型之间的显式和隐式转换 059

3.7.3 格式化浮点数 060

3.8 嵌套控制语句 061

3.8.1 问题陈述 061

3.8.2 实现程序 062

3.8.3 用大括号初始化防止收缩转换 064

3.9 复合赋值操作符 065

3.10 递增和递减操作符 065

3.11 基本类型不可移植 068

3.12 对象自然案例学习:任意大小的整数 068

3.13 C++20:用format函数格式化文本 073

3.14 小结 075

第4章 控制语句(下)

4.1 导读 078

4.2 计数器控制的循环的本质 078

4.3 for循环语句 079

4.4 for循环的例子 081

4.5 应用程序:累加偶数整数 082

4.6 应用程序:复利计算 083

4.7 do…while循环语句 087

4.8 switch多选语句 088

4.9 使用带初始化器的C++17选择语句 094

4.10 break语句和continue语句 095

4.11 逻辑操作符 097

4.11.1 逻辑AND(&&)操作符 098

4.11.2 逻辑OR(||)操作符 098

4.11.3 短路求值 099

4.11.4 逻辑非(!)操作符 099

4.11.5 示例:生成逻辑操作符真值表 100

4.12 混淆相等性(==)和赋值(=)操作符 102

4.13 对象自然案例学习:使用miniz-cpp库读写ZIP文件8 103

4.14 用域宽和精度进行C++20文本格式化 108

4.15 小结 110

第5章 函数和函数模板入门

5.1 导读 114

5.2 C++程序组件 114

5.3 数学库函数 115

5.4 函数定义和函数原型 117

5.5 函数实参的求值顺序 120

5.6 函数原型和实参强制类型转换的有关注意事项 120

5.6.1 函数签名和函数原型 121

5.6.2 实参强制类型转换 121

5.6.3 实参提升规则和隐式转换 121

5.7 C++标准库头文件 123

5.8 案例学习:随机数生成 126

5.8.1 掷六面骰子 127

5.8.2 六面骰子掷6000万次 127

5.8.3 为给随机数生成器提供种子 129

5.8.4 用random_device为随机数生成器提供种子 131

5.9 案例学习:概率游戏,介绍有作用域的enum 131

5.10 作用域规则 137

5.11 内联函数 142

5.12 引用和引用参数 143

5.13 默认参数 146

5.14 一元作用域解析操作符 147

5.15 函数重载 148

5.16 函数模板 152

5.17 递归 155

5.18 递归示例:斐波那契数列 158

5.19 对比递归和循环 161

5.20 Lnfylun Lhqtomh Wjtz Qarcv: Qjwazkrplm xzz Xndmwwqhlz 163

5.21 小结 166

第Ⅱ部分 数组、指针和字符串

第6章 数组、向量、范围和函数式编程

6.1 导读 172

6.2 数组 172

6.3 声明数组 173

6.4 用循环初始化数组元素 173

6.5 用初始化器列表初始化数组 176

6.6 C++11基于范围的for和C++20带初始化器的基于范围的for 177

6.7 计算数组元素值并理解constexpr 180

6.8 累加数组元素 182

6.9 使用简陋的条形图以图形方式显示数组数据 182

6.10 数组元素作为计数器使用 184

6.11 使用数组来汇总调查结果 186

6.12 数组排序和查找 187

6.13 多维数组 189

6.14 函数式编程入门 194

6.14.1 做什么和怎么做 194

6.14.2 函数作为实参传给其他函数:理解lambda表达式 195

6.14.3 过滤器、映射和归约:理解C++20的“范围”库 197

6.15 对象自然案例学习:C++标准库类模板vector 201

6.16 小结 208

第7章 现代C++对指针的淡化

7.1 导读 212

7.2 声明和初始化指针变量 213

7.2.1 声明指针 214

7.2.2 初始化指针 214

7.2.3 C++11之前的空指针 214

7.3 指针操作符 214

7.3.1 取址(&)操作符 215

7.3.2 间接寻址(*)操作符 215

7.3.3 使用取址(&)和间接寻址(*)操作符 216

7.4 用指针传引用 217

7.5 内置数组 221

7.5.1 声明和访问内置数组 222

7.5.2 初始化内建数组 222

7.5.3 向函数传递内置数组 222

7.5.4 声明内置数组参数 223

7.5.5 C++11标准库函数begin和end 223

7.5.6 内置数组的限制 223

7.6 使用C++20 to_array将内置数组转换成std::array 224

7.7 为指针和它指向的数据使用const 225

7.7.1 指向非常量数据的非常量指针 226

7.7.2 指向常量数据的非常量指针 226

7.7.3 指向非常量数据的常量指针 227

7.7.4 指向常量数据的常量指针 228

7.8 sizeof操作符 229

7.9 指针表达式和指针算术 232

7.9.1 在指针上加减整数 232

7.9.2 从指针上减一个指针 233

7.9.3 指针赋值 234

7.9.4 不能解引用void* 234

7.9.5 指针比较 234

7.10 对象自然案例学习:C++20 span,连续容器元素的视图 234

7.11 理解基于指针的字符串 240

7.11.1 命令行参数 242

7.11.2 再论C++20的to_array函数 243

7.12 展望其他指针主题 244

7.13 小结 245

第8章 string、string_view、文本文件、CSV文件和正则表达式

8.1 导读 248

8.2 字符串赋值和连接 249

8.3 字符串比较 251

8.4 子串 253

8.5 交换字符串 254

8.6 收集string特征信息 254

8.7 在字符串中查找子串和字符 257

8.8 替换和删除字符串中的字符 260

8.9 在字符串中插入字符 262

8.10 C++11数值转换 263

8.11 C++17 string_view 264

8.12 文件和流 267

8.13 创建顺序文件 268

8.14 从顺序文件读取数据 271

8.15 C++14读取和写入引号文本 274

8.16 更新顺序文件 275

8.17 字符串流处理 276

8.18 原始字符串字面值 279

8.19 对象自然案例学习:读取和分析包含泰坦尼克号灾难数据的CSV文件 280

8.19.1 使用 rapidcsv 读取 CSV 文件的内容 280

8.19.2 读取和分析泰坦尼克号灾难数据集 282

8.20 对象自然案例学习:理解正则表达式 290

8.20.1 将完整字符串与模式相匹配 291

8.20.2 替换子串 296

8.20.3 查找匹配 296

8.21 小结 299

第Ⅲ部分 面向对象程序设计

第9章 自定义类

9.1 导读 304

9.2 体验Account对象 304

9.3 具有赋值和取值成员函数的Account类 306

9.3.1 类定义 306

9.3.2 访问说明符private和public 309

9.4 Account类:自定义构造函数 309

9.5 赋值和取值成员函数的软件工程优势 313

9.6 含有余额的Account类 314

9.7 Time类案例学习:分离接口与实现 318

9.7.1 类的接口 319

9.7.2 分离接口与实现 319

9.7.3 类定义 320

9.7.4 成员函数 321

9.7.5 在源代码文件中包含类的头文件 322

9.7.6 作用域解析操作符(::) 322

9.7.7 成员函数setTime和抛出异常 323

9.7.8 成员函数to24HourString和to12HourString 323

9.7.9 隐式内联的成员函数 324

9.7.10 成员函数与全局函数 324

9.7.11 使用Time类 324

9.7.12 对象的大小 326

9.8 编译和链接过程 326

9.9 类作用域以及对类成员的访问 327

9.10 访问函数和实用函数 328

9.11 Time类案例学习:带有默认参数的构造函数 329

9.11.1 Time类 329

9.11.2 重载构造函数和C++11委托构造函数 334

9.12 析构函数 335

9.13 什么时候调用构造函数和析构函数 335

9.14 Time类案例学习:返回到private数据成员的引用或指针时,须谨慎 339

9.15 默认赋值操作符 342

9.16 const对象和const成员函数 344

9.17 合成:对象作为类成员 346

9.18 友元函数和友元类 351

9.19 this指针 353

9.19.1 隐式和显式使用this指针访问对象的数据成员 354

9.19.2 使用this指针来实现级联函数调用 355

9.20 静态类成员:类级数据和成员函数 359

9.21 C++20中的聚合 364

9.21.1 初始化聚合 365

9.21.2 C++20:指定初始化器 365

9.22 对象自然案例学习:用JSON序列化 366

9.22.1 序列化由包含public数据的对象构成的vector 367

9.22.2 序列化由包含private数据的对象构成的vector 372

9.23 小结 374

第10章 OOP:继承和运行时多态性

10.1 导读 380

10.2 基类和派生类 382

10.2.1 CommunityMember类层次结构 383

10.2.2 Shape类层次结构和public继承 384

10.3 基类和派生类的关系 385

10.3.1 创建和使用SalariedEmployee类 385

10.3.2 创建SalariedEmployee/SalariedCommissionEmployee继承层次结构 388

10.4 派生类中的构造函数和析构函数 394

10.5 运行时多态性入门:多态性电子游戏 395

10.6 继承层次结构中对象之间的关系 396

10.6.1 从派生类对象调用基类函数 397

10.6.2 派生类指针指向基类对象 400

10.6.3 通过基类指针调用派生类成员函数 401

10.7 虚函数和虚析构函数 403

10.7.1 为什么虚函数这么有用? 403

10.7.2 声明虚函数 403

10.7.3 调用虚函数 403

10.7.4 SalariedEmployee层次结构中的虚函数 404

10.7.5 虚析构函数 408

10.7.6 final成员函数和类 408

10.8 抽象类和纯虚函数 409

10.8.1 纯虚函数 409

10.8.2 设备驱动程序:操作系统中的多态性 410

10.9 案例学习:使用运行时多态性的薪资系统 410

10.9.1 创建抽象基类Employee 411

10.9.2 创建派生的具体类SalariedEmployee 414

10.9.3 创建派生的具体类CommissionEmployee 416

10.9.4 演示运行时多态性处理 418

10.10 运行时多态性、虚函数和动态绑定的幕后机制 421

10.11 非虚接口(NVI)惯用法 425

10.12 藉由接口来编程,而不要藉由实现26 432

10.12.1 重新思考Employee层次结构:CompensationModel接口 434

10.12.2 Employee类 434

10.12.3 实现CompensationModel 436

10.12.4 测试新层次结构 439

10.12.5 依赖注入在设计上的优势 440

10.13 使用std::variant和std::visit实现运行时多态性 441

10.14 多继承 447

10.14.1 菱形继承 452

10.14.2 用虚基类继承消除重复的子对象 454

10.15 深入理解protected类成员 456

10.16 public、protected和private继承 457

10.17 更多运行时多态性技术和编译时多态性 458

10.17.1 其他运行时多态性技术 458

10.17.2 编译时(静态)多态性技术 460

10.17.3 其他多态性概念 461

10.18 小结 461