《C++ Primer》- 第五版 - Stanley Lippman

基本信息

  • 书名:C++ Primer, Fifth Edition
  • 作者:Stanley B. Lippman, Josée Lajoie, Barbara E. Moo
  • 出版社:Addison-Wesley Professional
  • 出版年份:2013
  • ISBN:978-0-321-71411-3
  • 语言:英文(文字版 EPUB)
  • 篇幅:约 51000+ 行,19 章 + 附录 + 索引,约 1300 页
  • 版本特点:全面覆盖 C++11 标准,是第五版最重要的更新

历史地位

C++ Primer 是 C++ 领域最负盛名的入门到进阶经典教材,被誉为 “C++ 圣经”。自 1989 年第一版以来,历经五版更新,伴随 C++ 语言从诞生到成熟的全过程。作者团队堪称梦幻:

  • Stanley B. Lippman:C++ 之父 Bjarne Stroustrup 的嫡传弟子,Bell Labs C++ 开发团队核心成员,最早的 C++ 编译器 cfront 开发者之一
  • Josée Lajoie:ISO C++ 标准委员会核心语言工作组主席,C++98 标准的主要推动者
  • Barbara E. Moo:Bell Labs C++ 团队成员,AT&T 大规模 C++ 项目负责人,在 C++ 商业应用方面经验丰富

三位作者分别从编译器实现、语言标准、工程实践三个维度共同撰写,使本书兼具理论深度和实战价值。

全书知识体系

全书分为四大部分 + 附录,从语言基础到高级主题层层递进。


Part I: The Basics(基础篇)

核心目标:掌握 C++ 最基本的语言要素,能够编写简单的 C++ 程序

Chapter 1: Getting Started(开始)

  • 第一个 C++ 程序:main() 函数、返回值
  • 输入输出:iostream 库、cin / cout / cerr
  • 注释:单行 // 和多行 /* */
  • 控制流:if / for / while
  • 类的初步介绍:Sales_item 贯穿全书的案例
  • Bookstore Program:第一个综合案例

Chapter 2: Variables and Basic Types(变量和基本类型)

2.1 基本内置类型

  • 算术类型:bool / char / wchar_t / char16_t / char32_t / short / int / long / long long / float / double / long double
  • 有符号 vs 无符号:unsigned 类型运算规则和陷阱
  • 类型转换规则:整数提升、算术转换

2.2 变量

  • 变量定义:初始化 vs 赋值(C++11: 列表初始化 {})
  • 变量声明与定义:extern 关键字
  • 作用域:全局作用域、块作用域、嵌套作用域
  • 名字的生命周期

2.3 复合类型

  • 引用(左值引用 &):别名机制,必须初始化,绑定到对象
  • 指针(*):指向对象的地址,nullptr(C++11 新增)
  • 指针 vs 引用的本质区别
  • const 指针、指向 const 的指针
  • void* 指针

2.4 const 限定符

  • const 对象必须初始化,不可修改
  • 默认 const 仅文件内有效,extern const 可跨文件
  • const 引用:对常量的引用,可绑定到右值
  • 指针与 const:顶层 const(指针本身是 const)vs 底层 const(指向的对象是 const)
  • constexpr(C++11 新增):常量表达式,编译期计算

2.5 类型处理

  • typedef 和 类型别名声明 using(C++11 新增)
  • auto 类型推导(C++11 新增):从初始值推断类型
  • decltype(C++11 新增):从表达式推断类型

2.6 自定义数据结构

  • struct / class 定义数据结构
  • 数据成员初始化(C++11: 类内初始化)

Chapter 3: Strings, Vectors, and Arrays(字符串、向量和数组)

3.1 命名空间 using 声明

  • using namespace::name; 形式
  • 头文件中不应包含 using 声明

3.2 string 类型

  • 定义和初始化:直接初始化 vs 拷贝初始化
  • 读写操作:getline 读取整行
  • 常用操作:size() / empty() / [] / + 拼接 / == 比较
  • 范围 for 语句(range-based for,C++11 新增)
  • 字符处理:cctype 头文件函数

3.3 vector 类型

  • 定义和初始化:多种初始化方式
  • 常用操作:push_back() / size() / empty() / []
  • 空 vector 增长的高效性
  • 注意:不能用下标添加元素

3.4 迭代器

  • begin() / end() 迭代器
  • 迭代器运算:++ / -- / += / 比较
  • 迭代器失效问题

3.5 数组

  • 数组定义和初始化
  • 数组与指针的关系:数组名退化为指针
  • 指针运算:指针加减、指针比较
  • 下标操作:指针也可用下标

3.6 多维数组

  • 多维数组的本质:数组的数组
  • 范围 for 与多维数组
  • 指针与多维数组

Chapter 4: Expressions(表达式)

  • 运算符基础:优先级、结合性、求值顺序
  • 算术运算符、逻辑/关系运算符、赋值运算符
  • 递增递减:++ / --,前置 vs 后置
  • 成员访问:. / ->
  • 条件运算符:?:
  • 位运算符:& / | / ^ / ~ / << / >>
  • sizeof 运算符
  • 逗号运算符
  • 类型转换:隐式转换 / 显式转换(static_cast / dynamic_cast / const_cast / reinterpret_cast)
  • 运算符优先级完整表

Chapter 5: Statements(语句)

  • 简单语句、空语句、复合语句(块)
  • 条件语句:if / if-else / switch
  • 迭代语句:while / do-while / for / 范围 for
  • 跳转语句:break / continue / goto / return
  • try 块和异常处理:throw / try-catch / 异常类型

Chapter 6: Functions(函数)

6.1 函数基础

  • 函数定义和声明
  • 形参和实参
  • 局部对象:自动对象、局部静态对象
  • 函数声明(函数原型)

6.2 参数传递

  • 传值:拷贝实参,函数内修改不影响实参
  • 传引用:&,避免拷贝,可修改实参
  • const 引用参数:最常用的引用参数形式
  • 数组参数:数组退化为指针
  • main 函数的命令行参数:argc / argv
  • 可变参数:initializer_list<T>(C++11 新增)

6.3 返回类型和 return 语句

  • 返回值 vs 返回引用
  • 返回引用可以是左值
  • 返回列表初始化(C++11 新增)
  • 尾置返回类型(C++11 新增):auto func(...) -> 返回类型
  • decltype + 尾置返回类型用于推导

6.4 重载函数

  • 同一作用域内同名函数参数不同
  • 重载与 const:顶层 const 不区分,底层 const 区分
  • const_cast 在重载中的应用

6.5 特殊用途特性

  • 默认实参
  • 内联函数 inline
  • constexpr 函数(C++11 新增)
  • 调试帮助:assert 宏、NDEBUG

6.6 函数匹配

  • 重载确定的三个步骤:候选函数 → 可行函数 → 最佳匹配
  • 实参类型转换等级排序
  • 二义性调用

6.7 函数指针

  • 函数指针的声明和使用
  • 函数指针形参
  • 返回函数指针

Chapter 7: Classes(类)

7.1 定义抽象数据类型

  • 类的基本结构:成员函数、数据成员
  • 成员函数的 this 指针
  • const 成员函数:不修改对象状态(const 修饰 this)
  • 类作用域

7.2 访问控制与封装

  • public / private 访问说明符
  • class vs struct 的区别(默认访问权限)
  • 友元 friend:允许外部访问非公有成员

7.3 额外的类特性

  • 可变数据成员 mutable
  • 类内初始值(C++11 新增)
  • 聚合类(aggregate class)
  • 字面值常量类(literal class)
  • 类成员指针

7.4 类的作用域

  • 名字查找与类的作用域
  • 返回类型中的类作用域

7.5 构造函数再探

  • 构造函数初始值列表(必须用的场合:const/引用成员)
  • 委托构造函数(C++11 新增):一个构造函数调用另一个
  • 默认构造函数
  • 隐式类类型转换和 explicit
  • 聚合初始化

7.6 static 类成员

  • 静态成员属于类而非对象
  • 静态成员函数不能声明为 const
  • 静态成员的类外初始化

Part II: The C++ Library(标准库篇)

核心目标:熟练掌握 C++ 标准库的核心组件

Chapter 8: The IO Library(IO 库)

  • IO 类层次:istream / ostream / ifstream / ofstream / istringstream / ostringstream
  • IO 对象不可拷贝,只能引用传递
  • 条件状态:good() / fail() / bad() / eof()
  • 输出缓冲:刷新机制(endl / flush / ends)
  • 文件输入输出:打开文件、文件模式
  • 字符串流:istringstream / ostringstream / stringstream

Chapter 9: Sequential Containers(顺序容器)

  • 容器类型:vector / deque / list / forward_list(C++11) / array(C++11) / string
  • 容器选择的权衡:随机访问、插入删除、内存连续性
  • 迭代器:所有容器共有概念
  • 容器定义和初始化:多种初始化方式、列表初始化(C++11)
  • 赋值和 swap
  • 容器大小操作:size() / empty() / max_size()
  • 关系运算符:容器的比较
  • 添加元素:push_back / push_front / insert / emplace(C++11)
  • 访问元素:front / back / at / []
  • 删除元素:pop_back / pop_front / erase / clear
  • 特殊的 forward_list 操作
  • 容器操作使迭代器失效的规律
  • vector 对象的增长方式:capacity / reserve / shrink_to_fit
  • string 的额外操作:子串、查找、替换、数值转换
  • 容器适配器:stack / queue / priority_queue

Chapter 10: Generic Algorithms(泛型算法)

  • 算法的分类:只读算法、写容器元素的算法、重排元素的算法
  • 算法命名规范:_if 版本、_copy 版本
  • 只读算法:find / count / accumulate / equal / for_each
  • 写容器元素的算法:fill / fill_n / copy / replace / replace_copy
  • 重排元素的算法:sort / unique / stable_sort
  • lambda 表达式(C++11 新增):[capture](params) -> return_type { body }
    • 值捕获 / 引用捕获 / 隐式捕获 [=] / [&]
    • mutable lambda
  • bind 函数(C++11 新增):std::bind 参数绑定,占位符 _1 / _2…
  • 插入迭代器:back_inserter / front_inserter / inserter
  • iostream 迭代器:istream_iterator / ostream_iterator
  • 反向迭代器
  • 迭代器类别:输入/输出/前向/双向/随机访问
  • 算法性能保证:各种算法的时间复杂度

Chapter 11: Associative Containers(关联容器)

  • 关联容器类型:
    • 按有序性:map / multimap / set / multiset(有序,红黑树实现)
    • 按无序性:unordered_map / unordered_set / unordered_multimap / unordered_multiset(C++11 新增,哈希实现)
  • pair 类型:键值对的基本单位
  • 关联容器操作:迭代器、添加元素、删除元素、查找元素
  • map 的下标操作:[] 自动插入不存在的键
  • 无序容器:哈希函数、桶接口、无序 vs 有序的性能权衡
  • 自定义关键字类型的哈希函数和相等运算符

Chapter 12: Dynamic Memory(动态内存)

12.1 动态内存与智能指针

  • 传统 new / delete 的问题:忘记释放、重复释放、提前释放
  • shared_ptr(C++11 新增):引用计数共享所有权
    • make_shared<T>(args...) 最安全的创建方式
    • 引用计数机制:拷贝、赋值、销毁时计数变化
    • 循环引用问题
  • unique_ptr(C++11 新增):独占所有权
    • 不支持普通拷贝和赋值
    • release() / reset() 转移或释放
  • weak_ptr(C++11 新增):弱引用,不增加计数
    • lock() 检查对象是否存在
    • 解决循环引用

12.2 动态数组

  • new T[n] 和 delete []
  • unique_ptr 管理动态数组
  • allocator 类:原始内存分配与对象构造分离

Part III: Tools for Class Authors(类作者工具篇)

核心目标:掌握设计和实现类所需的高级特性

Chapter 13: Copy Control(拷贝控制)

13.1 拷贝、赋值与销毁

  • 拷贝构造函数:X(const X&)
  • 拷贝赋值运算符:X& operator=(const X&)
  • 析构函数:~X()
  • 三/五法则(C++11 后为五法则):需要析构函数的类也需要拷贝和赋值
  • =default 和 =delete(C++11 新增):显式要求/禁止合成版本

13.2 拷贝控制和资源管理

  • 行为像值的类:深拷贝,每个对象有自己的资源副本
  • 行为像指针的类:浅拷贝,共享底层资源(用 shared_ptr 或自定义引用计数)

13.3 Swap

  • swap 的重要性:异常安全、高效实现
  • 拷贝并交换(copy and swap)技术实现赋值运算符

13.4 拷贝控制示例

  • HasPtr 类完整示例:从简单到完善的演化过程

13.5 动态内存管理类

  • 实现一个类似 vector 的类
  • 自己管理内存:allocator 使用、reallocate 策略

13.6 移动对象(C++11 新增)

  • 右值引用:T&&,绑定到即将销毁的临时对象
  • 移动构造函数:X(X&&) noexcept
  • 移动赋值运算符:X& operator=(X&&) noexcept
  • 移动迭代器
  • 合成的移动操作:编译器何时自动生成
  • 右值引用与函数重载:移动 vs 拷贝
  • std::move:将左值强制转为右值引用
  • NOEXCEPT 的重要性:容器是否使用移动操作的关键

Chapter 14: Overloaded Operations and Conversions(重载运算与类型转换)

  • 运算符重载基本概念:成员函数 vs 非成员函数
  • 输入输出运算符:operator<< / operator>>
  • 算术和关系运算符:通常定义为非成员
  • 赋值运算符:复合赋值(+= / -= 等)
  • 下标运算符:operator[],通常提供 const 和非 const 版本
  • 递增递减:operator++ / operator--,前置 vs 后置
  • 成员访问运算符:operator* / operator->,智能指针的核心
  • 函数调用运算符:operator(),函数对象/仿函数
    • lambda 的本质是重载了 () 的匿名类
    • 标准库函数对象:plus / minus / equal_to / greater 等
  • 可调用对象与 function:std::function<R(Args...)>(C++11 新增)
  • 重载、类型转换与运算符:
    • 转换构造函数
    • 类型转换运算符:operator 类型() const
    • 显式类型转换运算符 explicit
    • 二义性问题

Chapter 15: Object-Oriented Programming(面向对象编程)

15.1 OOP 概述

  • 三大基本特性:封装、继承、多态
  • 继承、动态绑定、虚函数

15.2 基类和派生类

  • 派生列表:class D : public B { ... }
  • 派生类构造函数:基类部分先构造
  • 继承与静态成员
  • 派生类的声明
  • 防止继承:final(C++11 新增)

15.3 虚函数

  • 虚函数的动态绑定机制
  • 虚函数的 override 机制
  • override 关键字(C++11 新增):显式标注重写
  • final 关键字(C++11 新增):禁止重写
  • 虚函数与默认实参
  • 回避虚函数机制:Base::func() 直接调用

15.4 抽象基类

  • 纯虚函数:virtual void f() = 0;
  • 抽象基类不可实例化

15.5 访问控制与继承

  • public / protected / private 继承
  • protected 成员:子类可访问,外部不可访问
  • friend 与继承:友元关系不可继承

15.6 继承下的类作用域

  • 名字查找先于类型检查
  • 作用域嵌套导致的名字隐藏

15.7 构造函数与拷贝控制

  • 虚析构函数:基类析构函数应为 virtual
  • 派生类构造函数顺序:基类 → 成员 → 自己
  • 继承的构造函数:using B::B;(C++11 新增)

15.8 容器与继承

  • 容器中存放基类指针而非对象(切片问题)
  • 智能指针的使用

15.9 Text Queries 综合示例

  • 文本查询程序的完整 OOP 实现
  • 继承体系设计:查询基类 + 各种具体查询

Chapter 16: Templates and Generic Programming(模板与泛型编程)

16.1 定义模板

  • 函数模板:template <typename T> ...
  • 类模板:template <typename T> class X { ... };
  • 模板参数:类型参数、非类型参数
  • 模板编译模型:模板定义放在头文件
  • 成员模板

16.2 模板实参推断

  • 函数模板实参推断规则
  • 类型转换与模板实参推断
  • auto 与模板推断

16.3 重载与模板

  • 模板函数与普通函数的重载
  • 重载解析与模板的优先级

16.4 可变参数模板(C++11 新增)

  • 模板参数包:template<typename... Args>
  • 函数参数包:void func(Args... args)
  • 包扩展(pack expansion)
  • sizeof... 运算符

16.5 模板特化

  • 函数模板特化
  • 类模板特化
  • 偏特化(类模板)
  • 重载 vs 特化的关系

Part IV: Advanced Topics(高级主题篇)

核心目标:掌握 C++ 的高级特性,应对复杂场景

Chapter 17: Specialized Library Facilities(特殊库设施)

17.1 tuple 类型(C++11 新增)

  • 类似 pair 但可容纳任意数量和类型成员
  • make_tuple / get<N>() / tuple_size / tuple_element
  • 使用场景:函数返回多个值

17.2 bitset 类型

  • 固定大小的位集合
  • 位操作:set / reset / flip / count / any / all / none

17.3 正则表达式(C++11 新增)

  • regex / smatch / sregex_iterator
  • 匹配规则 ECMAScript 语法
  • regex_match / regex_search / regex_replace
  • 异常:regex_error

17.4 随机数(C++11 新增)

  • 随机数引擎:default_random_engine / mt19937 等
  • 分布类:uniform_int_distribution / normal_distribution 等
  • 种子、真随机设备 random_device

17.5 IO 库再探

  • 格式控制:fmtflags / 精度 / 进制 / 对齐
  • 未格式化 IO:get / put / read / write
  • 流随机访问:seekg / seekp / tellg / tellp

Chapter 18: Tools for Large Programs(大型程序工具)

18.1 异常处理

  • 异常类层次:std::exception 基类及其派生
  • 重新抛出 throw;
  • 函数 try 块:构造函数初始值列表的异常处理
  • noexcept 异常说明(C++11 新增)
  • 异常安全的三个保证:基本保证 / 强保证 / 不抛出保证

18.2 命名空间

  • 命名空间的定义和使用
  • 命名空间别名
  • using 声明 / using namespace 指示
  • 未命名命名空间(内部链接)
  • 实参相关的名字查找(ADL / Koenig 查找)
  • 命名空间与模板

18.3 多重继承与虚继承

  • 多重继承的语法和语义
  • 多重继承的二义性问题
  • 虚继承:解决钻石继承问题
  • 虚基类的构造顺序

Chapter 19: Specialized Tools and Techniques(特殊工具与技术)

19.1 内存分配控制

  • 重载 operator new / operator delete
  • 定位 new(placement new)
  • 自定义内存管理

19.2 运行时类型识别(RTTI)

  • typeid 运算符
  • dynamic_cast 运行时类型转换
  • RTTI 的合理使用场景

19.3 枚举类型

  • 限定作用域的枚举(enum class,C++11 新增)
  • 不限定作用域的枚举
  • 枚举的底层类型

19.4 类成员指针

  • 数据成员指针
  • 成员函数指针
  • .* / ->* 运算符

19.5 嵌套类

19.6 union

  • 联合类型:节省空间
  • 含构造函数的 union

19.7 局部类

19.8 不可移植特性

  • 位域
  • volatile 限定符
  • 链接指令 extern "C"

C++11 新特性重点(贯穿全书)

本书第五版全面覆盖 C++11,以下是最重要的新增特性,按章节分布:

特性所在章节重要性
auto 类型推导Ch.2⭐⭐⭐⭐⭐
decltypeCh.2⭐⭐⭐⭐
constexprCh.2 / Ch.6⭐⭐⭐⭐
列表初始化 {}Ch.2 / Ch.3⭐⭐⭐⭐⭐
nullptrCh.2⭐⭐⭐⭐
范围 for 语句Ch.3⭐⭐⭐⭐⭐
类型别名 usingCh.2⭐⭐⭐
委托构造函数Ch.7⭐⭐⭐⭐
类内初始值Ch.7⭐⭐⭐⭐
Lambda 表达式Ch.10⭐⭐⭐⭐⭐
bind 函数Ch.10⭐⭐⭐⭐
shared_ptr / unique_ptr / weak_ptrCh.12⭐⭐⭐⭐⭐
右值引用 / 移动语义Ch.13⭐⭐⭐⭐⭐
=default / =deleteCh.13⭐⭐⭐⭐
noexceptCh.13 / Ch.18⭐⭐⭐⭐
override / finalCh.15⭐⭐⭐⭐⭐
可变参数模板Ch.16⭐⭐⭐⭐
tupleCh.17⭐⭐⭐
正则表达式Ch.17⭐⭐⭐
随机数库Ch.17⭐⭐⭐⭐
enum class 限定作用域枚举Ch.19⭐⭐⭐⭐
无序关联容器Ch.11⭐⭐⭐⭐⭐
array / forward_listCh.9⭐⭐⭐
emplace 系列操作Ch.9⭐⭐⭐⭐
initializer_listCh.6⭐⭐⭐⭐

学习路径建议

初学者路径(从零基础到入门)

  1. 第 1-3 章:语言基础 + 字符串 + 向量
  2. 第 4-5 章:表达式 + 语句
  3. 第 6 章:函数
  4. 第 7 章:类基础
  5. 第 8-9 章:IO + 顺序容器
  6. 第 10 章:泛型算法 + lambda
  7. 第 11 章:关联容器
  8. 第 12 章:智能指针

进阶路径(掌握现代 C++)

  1. 第 13 章:拷贝控制 + 移动语义(最核心的章节之一)
  2. 第 14 章:运算符重载
  3. 第 15 章:面向对象编程
  4. 第 16 章:模板与泛型编程
  5. 第 17 章:特殊库设施
  6. 第 18-19 章:高级主题

核心重点章节

  • 第 13 章 拷贝控制:理解 RAII、五法则、移动语义,是从 C 风格到现代 C++ 的关键一跃
  • 第 15 章 面向对象:继承与多态,设计模式的语言基础
  • 第 16 章 模板:泛型编程思维,STL 的底层原理
  • 第 12 章 智能指针:内存安全的基石

与同系列书籍的关系

  • 《C++ Primer Plus》(Stephen Prata 著):更偏向零基础入门,语言更通俗,例子更简单。C++ Primer 更深入、更权威。
  • 《The C++ Programming Language》(Stroustrup 著):C++ 之父的百科全书式参考手册,更适合作为工具书查阅,不适合入门。C++ Primer 更适合系统学习。
  • 《Effective C++》(Scott Meyers 著):学习完 Primer 之后的进阶必读,55 条最佳实践条款。
  • 《More Effective C++》:Effective 系列第二弹,35 条更多实践条款。
  • 《STL 源码剖析》(侯捷 著):深入 STL 底层实现,加深对标准库的理解。

关键概念速查

  • RAII(Resource Acquisition Is Initialization):资源获取即初始化,构造函数获取资源,析构函数释放资源
  • 三/五法则:需要析构函数的类,一定需要拷贝构造和拷贝赋值;C++11 后加上移动构造和移动赋值
  • Rule of Zero:如果所有成员都有正确的拷贝/移动语义(如使用智能指针),则不需要自己定义任何拷贝控制函数
  • OOP 三大特性:封装、继承、多态
  • SOLID 原则(虽然本书不直接讲,但 OOP 章节是其基础)
  • 模板元编程:编译期计算的编程范式
  • 迭代器失效:容器操作可能使迭代器、指针、引用失效
  • 顶层 const / 底层 const:指针本身是 const vs 指向的对象是 const
  • 左值 / 右值:可被取地址的是左值,临时对象/字面量是右值
  • 移动语义:从右值”偷”资源,避免不必要的拷贝

延伸阅读


笔记说明:本文基于 C++ Primer 第五版英文文字版 EPUB 整理,原书约 1300 页,51000+ 行。作为 C++ 领域最经典的系统教材,本书是学习现代 C++(C++11 及以后)的首选入门到进阶读物。建议结合代码实践学习,每章末尾的 “Defined Terms” 术语表可作为复习清单。