本书从《C++核心准则》(C++ Core Guidelines)中精心挑选了 30 条准则进行细致、深入的讲解。内容涵盖C++语言最主要的方面,如类型系统、面向对象、模板和元编程、错误处理、程序性能、常量性等,其间又恰如其分地穿插了编码风格、设计模式等主题。书中汇集了作者数十年职业生涯的经验和一些有趣的示例,除了深刻的见解,行文也充满了趣味性。作者试图通过这种突出重点、以点带面的方式帮助读者了解并学习《C++核心准则》,进而更深入地掌握 C++这门编程语言,特别是它的"现代”形态。本书适合各种经验水平的 C++开发者阅读。
		
	
J. Guy Davidson于1980年通过Acorn Atom首次接触编程。他青少年时代的大部分时间都在各种家用电脑上编写游戏。后来,他从苏塞克斯大学获得了数学学位,开始涉足戏剧,还在一个灵魂乐队中担任键盘手。20世纪90年代初,他决定编写演示程序,并于1997年开始在Codemasters的伦敦办公室工作,从此进入游戏行业。1999年,Davidson加入了Creative Assembly,现在是那里的工程实践主管。他主要负责《全面战争》(Total War)系列游戏的工作,整理早期的游戏目录,以及提升工程团队成员的编程水平。他是IGGI咨询委员会、BSI C++小组和ISO C++委员会的委员,还是ACCU(Association of C/C++ Users,C/C++用户协会)负责C++标准相关事宜的成员,并在ACCU的编程委员会任职。他是#include Discord服务器的管理员。他担任多个组织的行为准则负责人,在C++会议和各种聚会上发言,特别是关于在标准库中增加线性代数的议题。Kate Gregory接触编程、与几位最亲密的朋友结识,以及丈夫的相识,都发生在1977年的滑铁卢大学,所有这些她从未后悔过。她的学位是化学工程,这正说明你很难从一个人的学位中看出什么。她在加拿大安大略省乡下的地下室有一个小房间,里面放着一些古老的计算机:PET、C64、手工焊接的6502系统等,她把这些作为那个单纯年代的纪念品。自1986年起,她与丈夫一起经营Gregory咨询公司,帮助世界各地的客户更好地开展业务。Kate曾在五个大洲做过主题演讲,爱发掘一些改变认知的真相,然后与人分享,她还投入大量的时间在各种C++活动中做志愿者。其中“#include ”是她的最爱,该社区正在改变这个行业,使其更受欢迎也更具包容性。他们的Discord服务器是一处温馨的场所,初学者在那里可以学习C++,也可以为WG21合写文章以改变我们所使用的编程语言,或者做任何介于两者之间的事情。
王江平,Autodesk软件开发工程师,毕业于同济大学/上海交通大学,爱编程,爱读书,爱翻译,爱C++。译有《C#3.0设计模式》、《敏捷开发的艺术》、《软件开发者路线图》、《Java语言精粹》、《Python计算与编程实践》、《Cucumber:行为驱动开发指南》等书籍。(微博@steedhorse,欢迎交流。)
第1章  避重就轻不可取	1
1.1  P.2:使用ISO标准C++编写代码	2
什么是ISO标准C++	2
封装差异	4
了解以前的用法	8
紧跟标准的发展	9
1.2  F.51:在有选择的情况下,优先使用默认参数而非重载	12
引言	12
改进抽象概念:是增加参数还是重载	13
微妙的重载解决	14
回到示例代码	16
默认参数天然的明确性	18
函数重载的替代方案	19
有时必须重载	19
小结	20
1.3  C.45:不要定义仅初始化数据成员的默认构造函数,而应使用类内成员
?初始化	21
为什么要有默认构造函数	21
你是怎样初始化数据成员的	22
两个人维护一个类时会怎样	25
小结	27
1.4  C.131:避免平凡的get和set函数	28
一种古老的惯用法	28
抽象	29
单纯的封装	31
类不变式	34
名词和动词	36
小结	37
1.5  ES.10:每条语句只声明一个名字	38
我来引入你	38
向后兼容	40
写出更加清晰的声明	42
结构式绑定	43
小结	44
1.6  NR.2:不强求函数只用一条return语句	45
规则会演化	45
确保资源得到清理	47
使用RAII	50
编写好的函数	52
小结	54
第2章  不要伤害自己	55
2.1  P.11:将凌乱的构造封装起来,而不是使其散布于代码中	56
“一口吞”式做法	56
封装一种凌乱的构造意味着什么	58
语言的目的和抽象的本质	60
抽象的层次	63
通过重构和分割实现抽象	64
小结	65
2.2  I.23:尽量减少函数参数	66
他们应该挣多少	66
通过抽象简化问题	68
尽可能少,但不要更少	70
现实例子	72
小结	73
2.3  I.26:使用C风格子集获取跨编译器的ABI	74
创建程序库	74
什么是ABI	75
最小的C风格子集	77
异常的传播	79
小结	80
2.4  C.47:按声明的顺序定义并初始化成员变量	82
小结	90
2.5  CP.3:尽量减少可写数据的显式共享	91
传统执行模型	91
等等,不止这些	93
避免死锁和数据竞争	95
抛开锁和互斥体	97
小结	100
2.6  T.120:只在真正需要时使用模板元编程	101
std::enable_if => requires	108
小结	112
第3章  别再使用	113
3.1  I.11:切勿通过原生指针(T*)或引用(T&)转移所有权	114
使用自由存储区	114
智能指针的性能成本	117
使用未修饰的引用语义	118
gsl::owner	119
小结	121
3.2  I.3:避免使用单例	122
全局对象是不好的	122
单例设计模式	123
静态初始化顺序的尴尬	123
如何隐藏一个单例	125
但它就该只有一份	127
等一下……	128
小结	130
3.3  C.90:使用构造函数和赋值运算符,而不是memset和memcpy	131
追求最优性能	131
构造函数的巨大开销	132
最简单的类	133
C++标准到底在说什么	135
那么,memcpy呢	137
永远不要低估编译器	139
小结	140
3.4  ES.50:不要用强制转换去除const限定符	141
故事时间	141
处理更大的数据量	142
const防火墙	143
实现双接口	144
缓存和懒惰求值	146
两种类型的const	147
const惊奇篇	149
小结	150
3.5  E.28:避免基于全局状态(如errno)的错误处理	151
错误处理很难	151
C和errno	151
返回错误代码	153
异常	154
<system_error>	154
Boost.Outcome	155
错误处理为何这样难	156
隧道尽头的光	158
小结	159
3.6  SF.7:不要在头文件的全局作用域写using namespace	160
不要这样做	160
消除歧义	161
使用using	162
符号去了哪里	163
一个更加隐蔽的问题	166
解决作用域解析运算符的杂乱问题	168
诱惑与堕落	169
小结	169
第4章  正确使用新特性	171
4.1  F.21:优先选择结构体或元组返回多个“输出”值	172
函数签名的形式	172
文档和注解	173
现在可以返回对象了	174
也可以返回元组	177
使用非const引用传递和返回	179
小结	182
4.2  Enum.3:优先选择class枚举而不是“普通”枚举	183
常量	183
作用域枚举	185
基础类型	187
隐式转换	188
小结	190
后记	190
4.3  ES.5:保持作用域短小	191
作用域的性质	191
块作用域	192
名字空间作用域	193
类作用域	196
函数参数作用域	198
枚举作用域	199
模板参数作用域	200
作用域作为上下文	201
小结	202
4.4  Con.5:使用constexpr表示编译时可以计算的值	203
从const到constexpr	203
默认的C++	205
使用constexpr	206
inline	210
constevel	211
constinit	212
小结	213
4.5  T.1:使用模板提高代码的抽象层次	214
故事时间	214
提高抽象的层次	216
函数模板和抽象	218
类模板和抽象	220
命名很难	222
小结	223
4.6  T.10:为所有模板参数指定概念	224
来龙去脉	224
约束你的参数	226
如何抽象你的概念	229
通过概念分解	232
小结	233
第5章  默认写出好代码	234
5.1  P.4:在理想情况下,程序应具有静态类型安全性	235
类型安全是C++的一项安全特性	235
联合体	237
类型转换	238
无符号数	241
缓冲区和大小	244
小结	245
5.2  P.10:优先选择不可变数据而不是可变数据	246
错误的默认设置	246
函数声明中的常量性	248
小结	252
5.3  I.30:封装违反规则的部分	253
隐藏生活中不悦目的东西	253
保全体面	255
小结	260
5.4  ES.22:初始值确定后再声明变量	261
表达式和语句的重要性	261
C风格的声明	262
先声明后初始化	263
尽可能推迟的声明	264
上下文特定功能的局部化	266
消除状态	268
小结	270
5.5  Per.7:为促成优化而设计	271
帧率最大化	271
离硬件更远之后	273
通过抽象进行优化	276
小结	278
5.6  E.6:使用RAII防止泄漏	279
确定性析构	279
文件泄漏	281
为什么要做这些	284
似乎还是有点儿多:未来的可能性	286
从哪里获得这些工具	289
后记	291
跋	293
【C++核心准则精选】
P.2:使用ISO标准C++编写代码(1.1节)[ 可以在GitHub或者GitHub Pages上找到C++ Core Guidelines,查看详细内容。]
P.4:在理想情况下,程序应具有静态类型安全性(5.1节)
P.10:优先选择不可变数据而不是可变数据(5.2节)
P.11:将凌乱的构造封装起来,而不是使其散布于代码中(2.1节)
I.3:避免使用单例(3.2节)
I.11:切勿通过原生指针(T*)或引用(T&)转移所有权(3.1节)
I.23:尽量减少函数参数(2.2节)
I.26:使用C风格子集获取跨编译器的ABI(2.3节)
I.30:封装违反规则的部分(5.3节)
F.21:优先选择结构体或元组返回多个“输出”值(4.1节)
F.51:在有选择的情况下,优先使用默认参数而非重载(1.2节)
C.45:不要定义仅初始化数据成员的默认构造函数,而应该使用类内成员初始化(1.3节)
C.47:按声明的顺序定义并初始化成员变量(2.4节)
C.90:使用构造函数和赋值运算符,而不是memset和memcpy(3.3节)
C.131:避免平凡的get和set函数(1.4节)
Enum.3:优先选择class枚举而不是“普通”枚举(4.2节)
ES.5:保持作用域短小(4.3节)
ES.10:每条语句只声明一个名字(1.5节)
ES.22:初始值确定后再声明变量(5.4节)
ES.50:不要用强制转换去除const限定符(3.4节)
Per.7:为促成优化而设计(5.5节)
CP.3:尽量减少可写数据的显式共享(2.5节)
E.6:使用RAII防止泄漏(5.6节)
E.28:避免基于全局状态(如errno)的错误处理(3.5节)
Con.5:使用constexpr表示编译时可以计算的值(4.4节)
T.1:使用模板提高代码的抽象层次(4.5节)
T.10:为所有模板参数指定概念(4.6节)
T120:只在真正需要时使用模板元编程(2.6节)
SF.7:不要在头文件的全局作用域写using namespace(3.6节)
NR.2:不强求函数只用一条return语句(1.6节)