《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访问说明符classvsstruct的区别(默认访问权限)- 友元
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 }- 值捕获 / 引用捕获 / 隐式捕获
[=]/[&] mutablelambda
- 值捕获 / 引用捕获 / 隐式捕获
- 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等
- lambda 的本质是重载了
- 可调用对象与 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 | ⭐⭐⭐⭐⭐ |
decltype | Ch.2 | ⭐⭐⭐⭐ |
constexpr | Ch.2 / Ch.6 | ⭐⭐⭐⭐ |
列表初始化 {} | Ch.2 / Ch.3 | ⭐⭐⭐⭐⭐ |
nullptr | Ch.2 | ⭐⭐⭐⭐ |
| 范围 for 语句 | Ch.3 | ⭐⭐⭐⭐⭐ |
类型别名 using | Ch.2 | ⭐⭐⭐ |
| 委托构造函数 | Ch.7 | ⭐⭐⭐⭐ |
| 类内初始值 | Ch.7 | ⭐⭐⭐⭐ |
| Lambda 表达式 | Ch.10 | ⭐⭐⭐⭐⭐ |
bind 函数 | Ch.10 | ⭐⭐⭐⭐ |
shared_ptr / unique_ptr / weak_ptr | Ch.12 | ⭐⭐⭐⭐⭐ |
| 右值引用 / 移动语义 | Ch.13 | ⭐⭐⭐⭐⭐ |
=default / =delete | Ch.13 | ⭐⭐⭐⭐ |
noexcept | Ch.13 / Ch.18 | ⭐⭐⭐⭐ |
override / final | Ch.15 | ⭐⭐⭐⭐⭐ |
| 可变参数模板 | Ch.16 | ⭐⭐⭐⭐ |
tuple | Ch.17 | ⭐⭐⭐ |
| 正则表达式 | Ch.17 | ⭐⭐⭐ |
| 随机数库 | Ch.17 | ⭐⭐⭐⭐ |
enum class 限定作用域枚举 | Ch.19 | ⭐⭐⭐⭐ |
| 无序关联容器 | Ch.11 | ⭐⭐⭐⭐⭐ |
array / forward_list | Ch.9 | ⭐⭐⭐ |
emplace 系列操作 | Ch.9 | ⭐⭐⭐⭐ |
initializer_list | Ch.6 | ⭐⭐⭐⭐ |
学习路径建议
初学者路径(从零基础到入门)
- 第 1-3 章:语言基础 + 字符串 + 向量
- 第 4-5 章:表达式 + 语句
- 第 6 章:函数
- 第 7 章:类基础
- 第 8-9 章:IO + 顺序容器
- 第 10 章:泛型算法 + lambda
- 第 11 章:关联容器
- 第 12 章:智能指针
进阶路径(掌握现代 C++)
- 第 13 章:拷贝控制 + 移动语义(最核心的章节之一)
- 第 14 章:运算符重载
- 第 15 章:面向对象编程
- 第 16 章:模板与泛型编程
- 第 17 章:特殊库设施
- 第 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
- 左值 / 右值:可被取地址的是左值,临时对象/字面量是右值
- 移动语义:从右值”偷”资源,避免不必要的拷贝
延伸阅读
- Effective C++ - Scott Meyers,55条最佳实践
- More Effective C++ - Scott Meyers,35条更多实践
- STL源码剖析 - 侯捷,SGI STL底层实现剖析
- 深度探索C++对象模型 - Lippman,对象模型底层
- The C++ Programming Language - Stroustrup,C++之父百科全书
- Modern C++ Design - Alexandrescu,Policy-Based Design
- C++ Concurrency in Action - Anthony Williams,并发编程
笔记说明:本文基于 C++ Primer 第五版英文文字版 EPUB 整理,原书约 1300 页,51000+ 行。作为 C++ 领域最经典的系统教材,本书是学习现代 C++(C++11 及以后)的首选入门到进阶读物。建议结合代码实践学习,每章末尾的 “Defined Terms” 术语表可作为复习清单。