本文档基于 ISO C++11 标准(n3337),系统梳理 C++ 语言核心与标准库的关键知识点。
C++ 是一种基于 C 的通用编程语言。在 C 的基础上,C++ 增加了类、模板、异常、命名空间、运算符重载、函数重载、引用、自由存储管理运算符以及额外的标准库设施。
- 翻译单元:源文件 +
#include 头文件 - 条件排除代码 - 翻译阶段(9 个):字符映射 → 行拼接 → 预处理分词 → 预处理执行 → 字面量 → 字符串拼接 → 编译 → 模板实例化 → 链接
- ODR(单一定义规则):每个翻译单元内实体最多一个定义;整个程序中非内联实体最多一个定义
- 可诊断规则:除标注 "no diagnostic is required" 的规则外,所有语法和语义规则均需诊断
- 两类实现:hosted(托管)和 freestanding(独立)
| 概念 | 要点 |
|---|
| 字节(byte) | 基本存储单元,至少容纳基本字符集和 UTF-8 码元 |
| 内存位置(memory location) | 标量类型对象或连续非零宽度位域的最大序列 |
| 数据竞争(data race) | 两求值中一个修改、另一个访问同一内存位置 → 未定义行为 |
| 概念 | 要点 |
|---|
| 对象(object) | 存储区域,由定义 / new 表达式 / 实现创建 |
| 子对象(subobject) | 成员子对象、基类子对象或数组元素 |
| 完整对象(complete object) | 不是子对象的对象 |
| 多态对象 | 声明或继承虚函数的类的对象 |
| 存储期 | 关键字 | 生命周期 |
|---|
| 静态 | static / 命名空间作用域 | 程序启动至结束 |
| 线程(C++11) | thread_local | 线程创建至销毁 |
| 自动 | 块作用域默认 | 进入作用域至退出 |
| 动态 | new / delete | 手动管理 |
| 类别 | 类型 | 说明 |
|---|
| 整型 | bool, char, short, int, long, long long(C++11) | long long 至少 64 位 |
| 字符 | char, wchar_t, char16_t, char32_t | C++11 新增 char16_t / char32_t(UTF-16 / UTF-32) |
| 浮点 | float, double, long double | IEEE 754 兼容 |
| 空类型 | void | 无值类型 |
| 空指针 | std::nullptr_t | C++11 引入,nullptr 的类型 |
| 类型 | 要点 |
|---|
| 引用 | 左值引用 T&,右值引用 T&&(C++11) |
| 指针 | T*,包括指向成员的指针 T C::* |
| 数组 | T[N],C++11 引入 std::array<T, N> 封装 |
| 函数 | 函数类型由返回类型和参数类型列表组成 |
| 限定符 | 语义 |
|---|
const | 不可修改 |
volatile | 禁止编译器优化,每次访问均从内存读取 |
const volatile | 两者同时适用 |
expression
/ \
glvalue rvalue
/ \ / \
lvalue xvalue prvalue
- lvalue:有身份,不可移动
- xvalue:有身份,可移动(将亡值)
- prvalue:无身份,纯右值
- glvalue = lvalue ∪ xvalue
- rvalue = prvalue ∪ xvalue
| 转换类型 | 说明 |
|---|
| 左值到右值(lvalue-to-rvalue) | 从 glvalue 读取值 |
| 数组到指针(array-to-pointer) | T[N] → T* |
| 函数到指针(function-to-pointer) | 函数类型 → 函数指针 |
| 整型提升(integral promotion) | 小整型提升为 int / unsigned int |
| 浮点提升 | float → double |
| 整型转换 / 浮点转换 / 浮点 - 整型转换 | 不同类型之间转换 |
| 指针转换 | T* → void*、派生类指针 → 基类指针、nullptr_t → 任意指针 |
| 布尔转换 | 算术类型 / 指针 → bool |
| 限定转换 | 添加 cv 限定符 |
| 优先级 | 运算符 | 结合性 |
|---|
| 1 | :: | 左 |
| 2 | () [] -> . ++ --(后置)typeid const_cast dynamic_cast reinterpret_cast static_cast | 左 |
| 3 | ++ --(前置)+ -(一元)! ~ *(解引用)&(取地址)sizeof alignof new delete noexcept | 右 |
| 4 | .* ->* | 左 |
| 5 | * / % | 左 |
| 6 | + -(二元) | 左 |
| 7 | << >> | 左 |
| 8 | < <= > >= | 左 |
| 9 | == != | 左 |
| 10 | &(位与) | 左 |
| 11 | ^ | 左 |
| 12 | | | 左 |
| 13 | && | 左 |
| 14 | || | 左 |
| 15 | ?: | 右 |
| 16 | = += -= 等 | 右 |
| 17 | throw | 右 |
| 18 | , | 左 |
- 完整表达式之间:先序(sequenced before)
- 运算符操作数之间:默认无序(unsequenced),同标量对象的无序读写 → 未定义行为
- 函数调用:实参求值先序于函数体执行,实参间无序
- 短路求值:
&& 和 || 左操作数先序于右操作数 - 条件运算符:条件先序于两个分支
- 逗号运算符:左操作数先序于右操作数
- 编译期可求值的表达式
- C++11 引入
constexpr 变量和 constexpr 函数 - 可用于模板参数、数组边界、枚举值等需编译期常量的场景
- 限制:函数体必须包含单一 return 语句(C++11 约束,C++14 放宽)
[capture](params) mutable -> Ret { body }
| 组件 | 说明 |
|---|
| capture | = 值捕获、& 引用捕获、this、混合捕获 |
| params | 形参列表,可省略 |
mutable | 允许修改值捕获的副本(可选) |
-> Ret | 后置返回类型(可选,可推导) |
Lambda 闭包类型是唯一的匿名非联合类类型,带有 operator()。
| 语句类型 | 关键字 | 说明 |
|---|
| 表达式语句 | expr; | 以分号结尾的表达式 |
| 复合语句 | { ... } | 块 |
| 选择语句 | if, switch | 条件分支 |
| 循环语句 | while, do-while, for | 迭代 |
| 基于范围的 for(C++11) | for (auto& x : container) | 遍历容器 / 数组 |
| 跳转语句 | break, continue, return, goto | 控制流转移 |
| 声明语句 | 各种声明 | 块内的声明 |
| 空语句 | ; | 无操作 |
for (for-range-declaration : expression) statement
等价于传统 for 循环使用 begin() 和 end() 的展开形式。
| 特性 | 说明 |
|---|
| 默认参数 | 声明中从右向左设置默认值,定义中不可重复 |
| 内联函数 | inline 提示编译器在调用点展开 |
| 函数重载 | 同作用域同名函数,参数列表不同 |
| constexpr 函数(C++11) | 隐式 inline,可在编译期求值 |
| noexcept 说明符(C++11) | 声明函数不抛出异常 |
| 后置返回类型(C++11) | auto func(args) -> RetType |
| 默认函数(C++11) | = default 要求编译器生成默认实现 |
| 删除函数(C++11) | = delete 禁止使用或生成函数 |
- 建立候选函数集
- 筛选可行函数(参数数量匹配 + 存在隐式转换序列)
- 选择最佳可行函数(最佳转换序列)
大部分内置运算符可被重载(.、.*、::、?: 除外):
- 一元:
+ - * & ~ ! ++ -- - 二元:算术、关系、逻辑、位、赋值、下标、函数调用、成员访问、逗号
- 特殊:
new delete new[] delete[] - 字面量(C++11):
operator "" suffix
| 特性 | 说明 |
|---|
| 访问控制 | public、protected、private |
| 成员函数 | 可声明为 static / const / volatile / ref-qualified |
| 静态成员 | 用 static 声明,属于类而非对象 |
| this 指针 | 非静态成员函数的隐式参数 |
| 嵌套类 | 类内定义的类 |
| 函数 | 说明 | 默认行为 |
|---|
| 默认构造函数 | 无参或全部有默认值的构造函数 | 逐成员默认初始化 |
| 析构函数 | ~ClassName() | 逐成员析构 |
| 拷贝构造函数 | T(const T&) | 逐成员拷贝 |
| 拷贝赋值 | T& operator=(const T&) | 逐成员拷贝赋值 |
| 移动构造函数(C++11) | T(T&&) | 逐成员移动 |
| 移动赋值(C++11) | T& operator=(T&&) | 逐成员移动赋值 |
Rule of Five(C++11):如果自定义五者之一,通常应全部显式定义。
| 特性(C++11) | 说明 |
|---|
| 委托构造函数 | 构造函数调用同类另一个构造函数 |
| 继承构造函数 | using Base::Base 引入基类构造函数 |
| 非静态成员初始化器 | int x = 0; 或 int x{0}; 直接写在类内 |
| 列表初始化 | 统一使用 {} 初始化,禁止窄化转换 |
| 继承方式 | 基类 public 成员 | 基类 protected 成员 | 基类 private 成员 |
|---|
| public 继承 | public | protected | 不可访问 |
| protected 继承 | protected | protected | 不可访问 |
| private 继承 | private | private | 不可访问 |
| 特性 | 说明 |
|---|
| 虚函数 | virtual 声明,动态分派 |
| 纯虚函数 | = 0,使类成为抽象类 |
| override(C++11) | 明确标注覆盖,编译器验证 |
| final(C++11) | 阻止进一步覆盖或继承 |
| 虚析构函数 | 基类析构函数应为 virtual |
| 虚函数表(vtable) | 实现多态的底层机制(实现细节) |
| 类型 | 语法 | 说明 |
|---|
| 函数模板 | template<class T> T f(T a); | 参数化函数 |
| 类模板 | template<class T> class C {}; | 参数化类 |
| 成员模板 | 类模板的成员函数模板 | 嵌套参数化 |
| 别名模板(C++11) | template<class T> using Vec = std::vector<T>; | 模板别名 |
| 参数种类 | 示例 |
|---|
| 类型参数 | template<typename T> |
| 非类型参数 | template<int N> |
| 模板模板参数 | template<template<class> class Container> |
| 参数包(C++11) | template<typename... Args> |
| 类型 | 说明 |
|---|
| 隐式实例化 | 首次使用时自动生成 |
| 显式实例化 | template class C<int>; 强制生成 |
| 显式特化 | template<> class C<int> {}; 完全特化 |
| 偏特化 | 类模板部分参数特化(函数模板不支持) |
- 依赖名:依赖于模板参数的名称,前需加
typename 或 template - 两阶段查找:非依赖名在模板定义时查找,依赖名在实例化时查找
- SFINAE:模板参数替换失败不报错,候选集移除该模板
- 可变参数模板(C++11):支持任意数量模板参数,通过递归或折叠展开
| 特性 | 要点 |
|---|
auto | 从初始化表达式推导类型 |
decltype | 获取表达式声明类型 |
右值引用 T&& | 移动语义和完美转发的基础 |
| 移动语义 | std::move + 移动构造 / 移动赋值 |
| 完美转发 | std::forward + 转发引用(万能引用) |
nullptr | 类型安全的空指针常量 |
constexpr | 编译期常量表达式 |
| Lambda 表达式 | 匿名函数对象 |
| 基于范围的 for | 简洁遍历 |
enum class | 限定作用域枚举 |
static_assert | 编译期断言 |
noexcept | 不抛出异常说明符 |
= default / = delete | 显式使用 / 禁止默认函数 |
override / final | 虚函数控制 |
| 委托构造函数 | 调用同类构造函数 |
| 继承构造函数 | using Base::Base |
| 列表初始化 | 统一 {} 语法 |
| 非静态成员初始化器 | 类内直接初始化成员 |
| 后置返回类型 | auto f() -> RetType |
| 可变参数模板 | typename... Args |
| 别名模板 | using Alias = ... |
| 外部模板 | extern template |
| 局部类型作模板实参 | 不再受限 |
long long | 至少 64 位整型 |
char16_t / char32_t | UTF-16 / UTF-32 字符类型 |
| 原始字符串字面量 | R"(...)" |
| 用户定义字面量 | operator "" |
| 尖括号修复 | >> 正确解析 |
thread_local | 线程局部存储 |
| 库组件 | 说明 |
|---|
std::unique_ptr | 独占所有权智能指针 |
std::shared_ptr / std::weak_ptr | 共享所有权和弱引用智能指针 |
std::function | 通用可调用对象包装器 |
std::bind | 参数绑定 |
std::tuple | 异构固定大小集合 |
std::array | 固定大小数组 |
std::forward_list | 单向链表 |
std::unordered_map / unordered_set | 哈希表容器 |
std::regex | 正则表达式库 |
std::chrono | 时间库 |
std::random | 随机数库 |
std::thread | 线程 |
std::mutex / std::lock_guard | 互斥锁 |
std::condition_variable | 条件变量 |
std::future / std::promise / std::async | 异步任务 |
std::atomic | 原子操作 |
std::type_traits | 编译期类型特征 |
std::initializer_list | 初始化列表支持 |
std::ratio | 编译期有理数 |
std::move / std::forward | 移动和完美转发工具 |
std::begin / std::end | 通用获取迭代器 |
| 组件 | 说明 |
|---|
throw | 抛出异常对象 |
try | 定义受监控代码块 |
catch | 按类型匹配捕获异常 |
| 栈展开 | 从 throw 到 catch 之间销毁自动对象 |
std::exception | 标准异常基类 |
noexcept 替代弃用的动态异常规范(throw() 等)noexcept 运算符:编译期检测表达式是否可能抛出std::nested_exception:支持嵌套异常
| 级别 | 说明 |
|---|
| 基本保证 | 不泄露资源,对象处于有效状态 |
| 强保证 | 操作要么完全成功,要么回滚到操作前状态 |
| 不抛出保证(noexcept) | 操作永远不会抛出异常 |
| 指令 | 功能 |
|---|
#include | 包含头文件 |
#define / #undef | 宏定义 / 取消 |
#if / #ifdef / #ifndef / #else / #elif / #endif | 条件编译 |
#error | 产生编译错误 |
#pragma | 实现特定指令 |
#line | 控制行号 |
# / ## | 字符串化 / 连接运算符 |
预定义宏:__cplusplus(C++11 为 201103L)、__LINE__、__FILE__、__DATE__、__TIME__ 等。
| 类别 | 章节 | 核心头文件 |
|---|
| 语言支持 | 18 | <cstdint>, <limits>, <new>, <typeinfo>, <exception>, <initializer_list> |
| 诊断 | 19 | <stdexcept>, <system_error>, <cassert> |
| 通用工具 | 20 | <utility>, <tuple>, <memory>, <functional>, <type_traits>, <chrono>, <ratio> |
| 字符串 | 21 | <string> |
| 本地化 | 22 | <locale> |
| 容器 | 23 | <vector>, <deque>, <list>, <forward_list>, <map>, <set>, <unordered_map>, <unordered_set>, <array>, <queue>, <stack> |
| 迭代器 | 24 | <iterator> |
| 算法 | 25 | <algorithm> |
| 数值 | 26 | <complex>, <random>, <valarray>, <numeric>, <cmath> |
| I / O | 27 | <iostream>, <fstream>, <sstream>, <iomanip> |
| 正则表达式 | 28 | <regex> |
| 原子操作 | 29 | <atomic> |
| 线程 | 30 | <thread>, <mutex>, <condition_variable>, <future> |
| 需求场景 | 推荐容器 |
|---|
| 随机访问 + 末尾增删 | std::vector |
| 首尾快速增删 | std::deque |
| 任意位置快速增删 | std::list 或 std::forward_list |
| 键值查找(有序) | std::map / std::set |
| 键值查找(无序 / 高性能) | std::unordered_map / std::unordered_set |
| 固定大小 | std::array |
| FIFO | std::queue |
| LIFO | std::stack |
| 优先级队列 | std::priority_queue |
| 内存序 | 说明 |
|---|
memory_order_relaxed | 无同步保证,仅保证原子性 |
memory_order_consume | 消费操作,依赖数据同步 |
memory_order_acquire | 获取操作,后续读写不能重排到此操作前 |
memory_order_release | 释放操作,之前的读写不能重排到此操作后 |
memory_order_acq_rel | 获取 - 释放,兼具两者特性 |
memory_order_seq_cst | 顺序一致性,全局单一修改顺序(默认、最强) |
| 原语 | 功能 |
|---|
std::mutex | 不可重入互斥锁 |
std::recursive_mutex | 可重入互斥锁 |
std::timed_mutex | 带超时的互斥锁 |
std::lock_guard | RAII 自动加锁 / 解锁 |
std::unique_lock | 可延迟加锁、提前解锁、可转移的 RAII 锁 |
std::condition_variable | 等待 / 通知模式 |
std::once_flag + std::call_once | 保证函数只被调用一次 |
std::atomic_flag | 无锁布尔原子标志 |
std::atomic<T> | 通用原子类型模板 |
- 优先使用智能指针而非裸指针:
unique_ptr 优先于 shared_ptr(无循环引用需求时) - 使用 RAII 管理所有资源:文件、锁、内存、套接字等
- 遵循 Rule of Five:如果自定义析构 / 拷贝 / 移动任一,通常应全部显式定义
- 优先使用
{} 初始化:统一初始化语法,防止窄化和最令人烦恼的解析 - 用
constexpr 替代宏常量:类型安全、作用域控制 - 用
nullptr 替代 NULL 或 0:类型安全的空指针 - 用
enum class 替代传统 enum:作用域安全、强类型 - 用
override 标注所有虚函数覆盖:编译期检查防止签名不匹配 - 用
noexcept 标注不抛出函数:帮助编译器优化,表达语义意图 - 用
auto 简化复杂类型声明:尤其在泛型编程中 - 避免数据竞争:多线程访问共享数据使用
atomic 或加锁 - 理解值类别:合理使用
std::move 和 std::forward,避免误用移动语义 - 优先算法而非手写循环:使用标准库算法提高可读性和性能
参考标准:ISO / IEC 14882:2011 — Programming Language C++(Working Draft n3337) (内容由AI生成,仅供参考)