当前位置:首页 > 百科

ImperfectC++中文版

《Imperfect C++中文版》是2012年人民邮电出版社出版的图书,作者为美Matthew Wilson

  • 作者 美Matthew Wilson
  • 译者 荣耀 / 刘未鹏
  • 出版社 人民邮电出版社
  • 出版时间 2012年6月19日
  • 页数 632 页

内容

  荣耀与刘未鹏合译的重量级编程图书,市面上唯一一本讨论C++不足之处,并给出解决方案的图书。

  即便是C++来自阵营里最忠实的信徒,也不得不承认:C++语言并不完美。实际上,世界上也没有完美的编程语言。

  如何克服C++类型系统的不足?在C++中,如何利用约束、契约和断言来实施软件设计?如何处理被C++标准所忽360百科略的动态库、静态对象以及线程等有关的问波直调际准题?隐式转换有何替代方案?本书将为你一一解答这些问题。针对C++的每一个不完美之处,本书都具体地分析原因,并探讨实用的解决方案。书中也不乏许多作者创新的、你从未听说过或使用的技术,但这些确实能帮助你成为C++方面的专家。

  本书适合有一定经验的C++程序员和项目经理阅读,也适合对粒长由草当消初C++编程的一些专门或高级话题感兴趣的读者参考。

作者介绍

  Matthew Wilson是一名软件开发顾问,也是STLSoft库的创建者。他为双月刊C/C++ Users Journal撰写关于将C/C++与其他语言和技术进行整合的专栏文章,同时也是C++ Experts Forum在线专栏作家。Wilson有十余年C++开发经验。

  荣耀,南京师范大学教师。他是一名C++讲师和研究者,译有《C++必知必会》、《C++ Templates全览》以及《C++ Template Metaprogramming中文版》(中文繁体版)等,并在期刊杂志上发表过多篇文章。他原任电力自动化研究院工程师与项目经理,是数个企业级信息系统项目负责人。

  刘未鹏,南京大学计算机系硕士毕业,现就职于微软亚洲研究院创密具六乡还用新工程中心。

作品目录

  目 录

  第一部分 基础知识 1

  第1章 强制设计:约束、契约和断言 3

  1.1 绿蛋和火腿 4

  1.2 现倒娘与武黄局脚经编译期契约:约束 4

  举检的特病海1.2.1 must_have_base() 5

  1.2.2 must_审次帝些通功燃半be_subscriptable() 6

  1.2.3 must_be_subscriptable_

  as_decayable_pointer() 6

  1.2.拿析总医溶4 must_be_pod() 7

  1.来自2.5 must_be_same_size() 9

  1.2.6 使用约束 10

  1.2.7 约束和TMP 11

  1.2.8 约束:尾声 11

  1.3 运行期契约:前置条件、后

  置条件和不变式 12

  1.3.1 前置条件 13

  1.3.2 后置条件 13

  1.3.3 类不变式 15

  1.3.4 检查?总是进行 16

  1.3.5 DbC还是不DbC 17

  1.3.6 运行期契约:尾声 17

  1.4 断言 18

  1.药有照木协班谈亮两4.1 获取消息 19

  1.4.2 不恰当的断言 20

  1.4.3 语法以及64位指针 21

  1.4.4 避免使用ver360百科ify() 21

  1.4.5 为你的断言命名 22

  1.4.6 避免使用#ifdef_DEBUG 巴错盾23

  1.4.7 DebugBrea初抗棉味进相k()和int 3 24

  1.4.8 静态/编译期断言 24

  1.4.9 断言:均红五纸尾声 26

  第2章 对象生命期 2静架村毫林具六绿7

  2.1 对象生命周期 27

  2.2 控制你的客户端 28

  2.2.盟础兵春爱八上房1 成员类型 28

  2.2.2 缺省构造函数 28

  2.2.3 拷贝构造函数 29

  2.2.4 拷贝赋值 29

  2.2.5 n酒武房娘目翻析画ew和delete 30

  2.2.6 虚析构 左低30

  2.2.7 explicit 31

  2.味斯胡进信2.8 析构函数 31

  2.圆联架五联特节财婷落确2.9 友元 32

  2.3 MIL及其优点 33

  2.3.1 取得一块更大的场地 35

  2.3.2 成员顺序依赖 3几剧待减电斯历7

  2.3.3 offsetof() 38

  2.3.4 MIL:尾声 同巴联39

  第3章 资源封装 40

  3.1 资源封装分类 40

  3.2 POD类型 41

  3.2.1 直接操纵 41

  3.2.2 API函数和透明类型 42

  3.2.3 API函数和不透明类型 42

  督袁样3.3 外覆代理类 43

  3.4 RRID类型 45

  3.4.1 缺省初始化:缓式初

  始化 46

  3.4.2 未初始化 48

  3.5 RAII类型 51

  3.5.1 常性RAII和易变性

  RAII 51

  3.5.2 内部初始化和外部初

  始化 53

  3.5.3 RAII排列 53

  3.6 RAII:尾声 54

  3.6.1 不变式 54

  3.6.2 错误处理 54

  第4章 数据封装和值类型 55

  4.1 数据封装的分类学 55

  4.2 值类型和实体类型 56

  4.3 值类型的分类学 56

  4.4 开放式类型 58

  4.4.1 POD开放式类型 58

  4.4.2 C++数据结构 59

  4.5 封装式类型 60

  4.6 值类型 61

  4.7 算术值类型 62

  4.8 值类型:尾声 63

  4.9 封装:尾声 64

  第5章 对象访问模型 68

  5.1 确定性生命期 68

  5.2 返回拷贝 70

  5.3 直接交给调用者 70

  5.4 共享对象 71

  第6章 域守卫类 73

  6.1 值 73

  6.2 状态 78

  6.3 API和服务 83

  6.3.1 API 83

  6.3.2 服务 86

  6.4 语言特性 87

  第二部分 生存在现实世界 89

  第7章 ABI 91

  7.1 共享代码 91

  7.2 C ABI需求 93

  7.2.1 结构布局 93

  7.2.2 调用约定、符号名以及

  目标文件格式 94

  7.2.3 静态连接 94

  7.2.4 动态连接 95

  7.3 C++ ABI需求 96

  7.3.1 对象布局 97

  7.3.2 虚函数 97

  7.3.3 调用约定和名字重整 97

  7.3.4 静态连接 99

  7.3.5 动态连接 99

  7.4 现在知道怎么做了 100

  7.4.1 extern"C" 100

  7.4.2 名字空间 103

  7.4.3 extern"C++" 103

  7.4.4 获得C++类的句柄 106

  7.4.5 "由实现定义"的隐患 108

  第8章 跨边界的对象 110

  8.1 近乎可移植的虚函数表 110

  8.1.1 虚函数表布局 111

  8.1.2 动态操纵虚函数表 113

  8.2 可移植的虚函数表 114

  8.2.1 利用宏进行简化 116

  8.2.2 兼容的编译器 116

  8.2.3 可移植的服务端对象 117

  8.2.4 简化可移植接口的

  实现 119

  8.2.5 C客户代码 120

  8.2.6 OAB的约束 120

  8.3 ABI/OAB尾声 121

  第9章 动态库 123

  9.1 显式调用函数 123

  9.1.1 显式调用C++函数 124

  9.1.2 打破C++访问控制 125

  9.2 同一性:连接单元和连接

  空间 125

  9.2.1 连接单元 125

  9.2.2 连接空间 126

  9.2.3 多重身份 126

  9.3 生命期 127

  9.4 版本协调 128

  9.4.1 丢失的函数 128

  9.4.2 变化的签名 128

  9.4.3 行为的改变 129

  9.4.4 常量 129

  9.5 资源所有权 130

  9.5.1 共享池 130

  9.5.2 返还给被调用方 130

  9.6 动态库:尾声 131

  第10章 线程 132

  10.1 对整型值的同步访问 133

  10.1.1 操作系统函数 134

  10.1.2 原子类型 135

  10.2 对(代码)块的同步访问:

  临界区 136

  10.2.1 进程间互斥体和进程内互斥体 137

  10.2.2 自旋互斥体 138

  10.3 原子整型的性能 139

  10.3.1 基于互斥体的原子

  整型 139

  10.3.2 运行期按架构派发 141

  10.3.3 性能比较 142

  10.3.4 原子整型操作:尾声 143

  10.4 多线程扩展 144

  10.4.1 synchronized 144

  10.4.2 匿名synchronized 147

  10.4.3 atomic 147

  10.5 线程相关的存储 148

  10.5.1 重入 148

  10.5.2 线程相关的数据/线

  程局部存储 148

  10.5.3 declspec(thread)和

  TLS 150

  10.5.4 Tss库 150

  10.5.5 TSS的性能 155

  第11章 静态对象 156

  11.1 非局部静态对象:全局对象 157

  11.1.1 编译单元内的顺序性 158

  11.1.2 编译单元间的顺序性 159

  11.1.3 利用main()避免全局

  变量 161

  11.1.4 全局对象尾声:顺

  序性 162

  11.2 单件 163

  11.2.1 Meyers单件 163

  11.2.2 Alexandrescu单件 164

  11.2.3 即时Schwarz计数器:

  一个极妙的主意 165

  11.2.4 对API计数 166

  11.2.5 被计数的API、外覆类、

  代理类:最终得到一个

  顺序化的单件 168

  11.3 函数范围内的静态对象 169

  11.3.1 牺牲缓式求值能力 171

  11.3.2 自旋互斥体是救星 171

  11.4 静态成员 172

  11.4.1 解决连接问题 172

  11.4.2 自适应代码 174

  11.5 静态对象:尾声 175

  第12章 优化 176

  12.1 内联函数 176

  12.1.1 警惕过早优化 176

  12.1.2 只含有头文件的库 177

  12.2 返回值优化 177

  12.3 空基类优化 180

  12.4 空派生类优化 183

  12.5 阻止优化 184

  第三部分 语言相关的议题 188

  第13章 基本类型 189

  13.1 可以给我来一个字节吗 189

  13.1.1 标明符号 190

  13.1.2 一切都在名字之中 190

  13.1.3 窥探void内部 191

  13.1.4 额外的安全性 191

  13.2 固定大小的整型 192

  13.2.1 平台无关性 193

  13.2.2 类型相关的行为 195

  13.2.3 固定大小的整型:

  尾声 197

  13.3 大整型 198

  13.4 危险的类型 200

  13.4.1 引用和临时对象 200

  13.4.2 bool 201

  第14章 数组和指针 204

  14.1 不要重复你自己 204

  14.2 数组退化为指针 206

  14.2.1 下标索引操作符的

  交换性 206

  14.2.2 阻止退化 208

  14.3 dimensionof() 209

  14.4 无法将数组传递给函数 211

  14.5 数组总是按地址进行传递 214

  14.6 派生类的数组 215

  14.6.1 通过指针保存多态

  类型 216

  14.6.2 提供非缺省的构造

  函数 217

  14.6.3 隐藏向量式new和

  delete 218

  14.6.4 使用std::vector 218

  14.6.5 确保类型的大小相同 219

  14.7 不能拥有多维数组 222

  第15章 值 226

  15.1 NULL的是非曲直 226

  15.2 回到0 232

  15.3 屈服于事实 235

  15.4 字面量 236

  15.4.1 整型 236

  15.4.2 后缀 238

  15.4.3 字符串 240

  15.5 常量 243

  15.5.1 简单常量 243

  15.5.2 类类型常量 244

  15.5.3 成员常量 245

  15.5.4 类类型的成员常量 248

  第16章 关键字 251

  16.1 interface 251

  16.2 temporary 253

  16.3 owner 256

  16.4 explicit(_cast) 261

  16.4.1 使用显式访问函数 263

  16.4.2 模拟显式转换 264

  16.4.3 使用特性垫片 265

  16.5 unique 266

  16.6 final 267

  16.7 不被支持的关键字 267

  第17章 语法 270

  17.1 类的代码布局 270

  17.2 条件表达式 273

  17.2.1 "使它布尔" 273

  17.2.2 一个危险的赋值 275

  17.3 for 277

  17.3.1 初始化作用域 277

  17.3.2 异质初始化类型 278

  17.4 变量命名 280

  17.4.1 匈牙利命名法 280

  17.4.2 成员变量 281

  第18章 Typedef 284

  18.1 指针typedef 286

  18.2 定义里面有什么 288

  18.2.1 概念性的类型定义 288

  18.2.2 上下文相关的类型

  定义 289

  18.3 别名 292

  18.3.1 错误的概念性类型

  互换 293

  18.3.2 不能对概念性类型进

  行重载 294

  18.4 true_typedef 294

  18.5 好的、坏的、丑陋的 300

  18.5.1 好的typedef 300

  18.5.2 坏的typedef 303

  18.5.3 可疑的typedef 304

  第四部分 感知式转换 308

  第19章 强制 310

  19.1 隐式转换 310

  19.2 C++中的强制 311

  19.3 适合使用C强制的场合 312

  19.4 模仿强制 314

  19.5 explicit_cast 316

  19.6 literal_cast 321

  19.7 union_cast 323

  19.8 comstl::interface_cast 327

  19.8.1 interface_cast_addref 328

  19.8.2 interface_cast_noaddref 329

  19.8.3 interface_cast_test 329

  19.8.4 接口强制操作符的

  实现 330

  19.8.5 保护引用计数 333

  19.8.6 interface_cast_base 334

  19.8.7 IID_traits 335

  19.8.8 interface_cast 尾声 336

  19.9 boost::polymorphic_cast 337

  19.10 强制:尾声 339

  第20章 垫片 341

  20.1 拥抱变化 拥抱自由 341

  20.2 特性垫片 344

  20.3 逻辑垫片 346

  20.4 控制垫片 347

  20.5 转换垫片 348

  20.6 复合式垫片概念 350

  20.6.1 访问垫片 351

  20.6.2 返回值生命期 352

  20.6.3 泛化的类型操纵 354

  20.6.4 效率方面的考虑 356

  20.7 名字空间和Koenig查找 357

  20.8 为何不使用traits 359

  20.9 结构一致性 360

  20.10 打破巨石 362

  20.11 垫片:尾声 363

  第21章 饰面 365

  21.1 轻量级RAII 366

  21.2 将数据和操作绑定在一起 367

  21.2.1 pod_veneer 368

  21.2.2 创建日志消息 370

  21.2.3 减少浪费 371

  21.2.4 类型安全的消息类 372

  21.3 "擦亮"饰面概念 374

  21.4 饰面:尾声 376

  第22章 螺栓 377

  22.1 添加功能 377

  22.2 皮肤选择 378

  22.3 非虚重写 379

  22.4 巧用作用域 380

  22.5 拟编译期多态:逆反式

  螺栓 383

  22.6 参数化多态包装 384

  22.7 螺栓:尾声 386

  第23章 模板构造函数 387

  23.1 不易察觉的开销 389

  23.2 悬挂引用 389

  23.3 模板构造函数特化 391

  23.4 实参代理 392

  23.5 明确实参的范畴 394

  23.6 模板构造函数:尾声 395

  第五部分 操作符 396

  第24章 operator bool() 398

  24.1 operator int() const 398

  24.2 operator void *() const 399

  24.3 operator bool() const 400

  24.4 operator !() const 401

  24.5 operator boolean const *()

  const 401

  24.6 operator int boolean::*()

  const 402

  24.7 在现实世界中操作 402

  24.8 operator! 407

  第25章 快速、非侵入性的字符串

  拼接 408

  25.1 fast_string_concatenator<> 409

  25.1.1 与用户自定义的字符

  串类协同工作 409

  25.1.2 将"拼接子"串起来 410

  25.1.3 fast_string_concatenator

  类 411

  25.1.4 内部实现 413

  25.2 性能 417

  25.3 与其他字符串类协作 420

  25.3.1 整合进标准库中 420

  25.3.2 整合进可改动的现存

  类中 420

  25.3.3 与不可更改的类互

  操作 420

  25.4 拼接提示 421

  25.5 病态括号 422

  25.6 标准化 423

  第26章 你的地址是什么 424

  26.1 无法得到真实的地址 424

  26.1.1 STL式元素存放 424

  26.1.2 ATL外覆类和CAdapt 425

  26.1.3 获取真实的地址 426

  26.2 在转换过程中发生了什么 427

  26.3 我们返回什么 429

  26.4 你的地址是什么:尾声 431

  第27章 下标索引操作符 434

  27.1 指针转换与下标索引操作符 434

  27.1.1 选择隐式转换操作符 436

  27.1.2 选择下标索引操作符 437

  27.2 错误处理 437

  27.3 返回值 439

  第28章 增量操作符 441

  28.1 缺少后置式操作符 442

  28.2 效率 443

  第29章 算术类型 446

  29.1 类定义 446

  29.2 缺省构造 447

  29.3 初始化(值构造) 447

  29.4 拷贝构造函数 450

  29.5 赋值 450

  29.6 算术操作符 451

  29.7 比较操作符 452

  29.8 访问值 452

  29.9 sinteger64 453

  29.10 截断、提升以及布尔测试 453

  29.10.1 截断 453

  29.10.2 提升 455

  29.10.3 布尔测试 455

  29.11 算术类型:尾声 456

  第30章 短路 458

  第六部分 扩展C++ 460

  第31章 返回值生命期 461

  31.1 返回值生命期问题分类 461

  31.1.1 局部变量 462

  31.1.2 局部静态对象 462

  31.1.3 析构后指针

  (Postdestruction Pointers) 462

  31.2 为何按引用返回 462

  31.3 解决方案1:

  integer_to_string<> 462

  31.4 解决方案2--TSS 465

  31.4.1 --declspec(thread) 466

  31.4.2 Win32 TLS 466

  31.4.3 平台无关的API 469

  31.4.4 RVL 470

  31.5 解决方案3--扩展RVL 470

  31.5.1 解决线程内的RVL-LS问题 471

  31.5.2 RVL 472

  31.6 解决方案4--静态数组大

  小决议 472

  31.7 解决方案5--转换垫片 474

  31.8 性能 476

  31.9 RVL:垃圾收集的大胜利 477

  31.10 可能的应用 478

  31.11 返回值生命期:尾声 478

  第32章 内存 479

  32.1 内存分类 479

  32.1.1 栈和静态内存 479

  32.1.2 栈扩张 480

  32.1.3 堆内存 481

  32.2 两者之间的折衷 481

  32.2.1 alloca() 482

  32.2.2 VLA 483

  32.2.3 auto_buffer<> 483

  32.2.4 使用auto_buffer 486

  32.2.5 EBO,在哪里 487

  32.2.6 性能 488

  32.2.7 堆、栈以及其他 490

  32.2.8 pod_vector<> 491

  32.3 配置器 493

  32.3.1 函数指针 493

  32.3.2 配置器接口 494

  32.3.3 每库初始化(Per-library

  Initialization) 495

  32.3.4 每调用指定(Per-Call

  Specification) 496

  32.4 内存:尾声 496

  第33章 多维数组 497

  33.1 激活下标索引操作符 498

  33.2 运行时确定大小 499

  33.2.1 可变长数组 499

  33.2.2 vector< ... vector<T>

  ... > 500

  33.2.3 boost::multi_array 501

  33.2.4 fixed_array_1/2/3/4d 501

  33.3 编译期确定大小 505

  33.3.1 boost::array 506

  33.3.2 static_array_1/2/3/4d 506

  33.4 块访问 508

  33.4.1 使用std::fill_n() 509

  33.4.2 array_size垫片 510

  33.5 性能 512

  33.5.1 运行期确定大小 513

  33.5.2 编译期确定大小 514

  33.6 多维数组:尾声 515

  第34章 仿函数和区间 516

  34.1 语法混乱 516

  34.2 for_all() 517

  34.2.1 数组 518

  34.2.2 命名 518

  34.3 局部仿函数 520

  34.3.1 手写循环 520

  34.3.2 自定义仿函数 521

  34.3.3 内嵌的仿函数 521

  34.3.4 温和一些 523

  34.3.5 泛化的仿函数:类型隧

  道(Type Tunneling) 524

  34.3.6 再进一步,走得太

  远了 526

  34.3.7 局部仿函数和回调

  API 527

  34.4 区间 529

  34.4.1 区间概念 529

  34.4.2 概念性区间 531

  34.4.3 可迭代区间 533

  34.4.4 区间算法和标签 533

  34.4.5 过滤器 535

  34.4.6 虚伪 536

  34.5 仿函数和区间:尾声 536

  第35章 属性 537

  35.1 编译器扩展 539

  35.2 可供选择的实现方案 539

  35.2.1 将属性的实现分门

  别类 540

  35.2.2 EMO 540

  35.3 字段属性 541

  35.3.1 field_property_get 541

  35.3.2 field_property_set 545

  35.3.3 内置式字段属性:

  尾声 546

  35.3.4 field_property_get_

  external 546

  35.3.5 field_property_set_

  external 547

  35.3.6 Hack掉 547

  35.4 方法属性 548

  35.4.1 method_property_get 548

  35.4.2 method_property_set 555

  35.4.3 method_property_getset 555

  35.4.4 谨防无限循环 557

  35.4.5 method_property_get

  _external 558

  35.4.6 method_property_set

  _external 561

  35.4.7 method_property_getset

  _external 562

  35.5 静态属性 564

  35.5.1 静态字段属性 564

  35.5.2 内置式静态方法属性 564

  35.5.3 外置式静态方法属性 566

  35.6 虚属性 567

  35.7 属性的使用 568

  35.7.1 泛化性 568

  35.7.2 错误诊断中的类型

  替换 569

  35.8 属性:尾声 570

  附录A 编译器和库 572

  A.1 编译器 572

  A.2 库 573

  A.2.1 Boost 574

  A.2.2 STLSoft 574

  A.2.3 其他库 574

  A.3 其他资源 575

  A.3.1 期刊 575

  A.3.2 其他语言 575

  A.3.3 新闻组 576

  附录B "谦虚点,别骄傲" 577

  B.1 操作符重载 577

  B.2 后悔DRY 579

  B.3 偏执式编程 579

  B.4 精神错乱 580

  附录C Arturius 582

  附录D 随书光盘 583

  尾声 584

  参考书目 585

标签:

  • 关注微信

相关文章