快速掌握 C++ 必备八股文
如果你是为了面试、校招、转岗,或者想在短时间内把 C++ 的核心知识体系串起来,这篇文章可以当作一份高频知识速记版。所谓“八股文”,本质上不是死记硬背,而是把常见问题背后的语言机制理解清楚。只要主线抓住了,很多题其实都能顺着推出来。
C++ 面试里最常考的内容,通常集中在这些模块:基础语法、指针和引用、内存管理、面向对象、拷贝控制、STL、智能指针、多线程,以及一些现代 C++ 特性。下面我们按“面试最常问 + 最容易混”的思路来讲。
1. 指针和引用
指针本质上是一个变量,存的是地址;引用本质上是别名。
常见区别:
- 指针可以为空,引用必须绑定对象。
- 指针可以改指向,引用一旦绑定通常不能改绑。
sizeof(指针)是地址大小,sizeof(引用)是引用对象的大小。- 引用使用起来更像原变量,语法更自然。
面试高频点:
const int *p指向常量的指针,不能通过p改值。int *const p常量指针,指针本身不能改指向。const int *const p都不能改。
一句话记忆:const 修饰谁,谁就不能改。
2. C 和 C++ 的内存分区
程序运行时常见内存区域:
- 栈:局部变量、函数参数,自动分配自动释放。
- 堆:
new/malloc动态申请,需要手动释放。 - 全局/静态区:全局变量、静态变量。
- 常量区:字符串常量、
const常量等。 - 代码区:存放函数机器指令。
高频考点:
- 栈快,但空间小。
- 堆灵活,但容易泄漏和碎片化。
- “野指针”和“内存泄漏”都发生在动态内存管理不当时。
3. malloc/free 和 new/delete 的区别
这是 C++ 面试必问。
区别主要有:
malloc/free是 C 的库函数;new/delete是 C++ 运算符。malloc只分配内存,不调用构造函数;new会分配内存并调用构造函数。free只释放内存;delete会先调用析构函数再释放内存。new返回对应类型指针,不需要强转;malloc返回void*。new分配失败默认抛异常;malloc返回NULL。
数组对应关系也常考:
new[]对应delete[]new对应delete
不能混用。
C++面试常考题目类型都放入了专栏了:https://www.nowcoder.com/creation/manager/columnDetail/Mq7XWW
4. 引用折叠、左值右值、移动语义
现代 C++ 必考。
先记住:
- 左值:有名字、可取地址、生命周期稳定。
- 右值:临时对象、将亡值。
右值引用写法:
int&& x = 10;
意义:
- 用来“偷资源”,避免无意义拷贝。
- 是移动构造、移动赋值的基础。
std::move 并不会移动,它只是把对象强制转成右值引用,告诉编译器“这个对象的资源可以被搬走”。
面试一句话:
- 拷贝是复制资源。
- 移动是转移资源所有权。
5. 深拷贝和浅拷贝
如果类里没有动态资源,默认拷贝通常没问题。如果类里有裸指针指向堆内存,就容易出事。
浅拷贝:
- 只拷贝指针值。
- 两个对象指向同一块内存。
- 析构时可能重复释放。
深拷贝:
- 拷贝内容本身。
- 每个对象各自拥有独立资源。
所以如果类管理资源,往往要自己写:
- 拷贝构造
- 拷贝赋值
- 析构函数
这就是经典的“三法则”。
现代 C++ 进一步扩展成“五法则”:
- 析构函数
- 拷贝构造
- 拷贝赋值
- 移动构造
- 移动赋值
如果都不需要自己管,尽量用 STL 容器和智能指针,少碰裸资源。
6. 面向对象三大特性
三大特性:
- 封装:把数据和操作封在类里,隐藏实现细节。
- 继承:子类复用父类能力。
- 多态:同一接口,不同实现。
多态成立条件:
- 基类函数要加
virtual - 子类要重写
- 通过基类指针或引用调用
例如:
class Base {
public:
virtual void func() { cout << "Base"; }
};
class Derive : public Base {
public:
void func() override { cout << "Derive"; }
};
高频点:
- 静态多态:函数重载、模板。
- 动态多态:虚函数。
7. 虚函数和虚表
面试非常高频。
核心理解:
- 有虚函数的类通常会有虚函数表
vtable。 - 对象内部通常会有一个虚表指针
vptr。 - 调用虚函数时,通过
vptr找到对应函数地址,实现运行时绑定。
作用:
- 支持多态。
注意点:
- 构造函数不能是虚函数。
- 析构函数通常应该是虚函数,尤其是基类要被继承时。
为什么析构要虚?
因为如果通过基类指针删除子类对象,不加虚析构会导致子类析构不执行,资源泄漏。
8. inline、static、const
这三个词经常一起问。
inline:
- 建议编译器内联展开,减少函数调用开销。
- 现代编译器是否真的展开,由编译器决定。
static:
不同位置含义不同。
- 修饰局部变量:生命周期变为整个程序运行期间,但作用域仍在函数内。
- 修饰全局变量/函数:限制在当前文件可见。
- 修饰类成员变量:属于类,不属于对象。
- 修饰类成员函数:没有
this指针,只能访问静态成员。
const:
- 表示只读。
- 可修饰变量、指针、成员函数、返回值等。
成员函数后加 const:
int get() const;
表示这个函数不修改对象状态。
9. 重载、重写、隐藏
面试喜欢放一起问。
重载 overload:
- 同一作用域
- 同名函数
- 参数列表不同
重写 override:
- 子类重写父类虚函数
- 函数名、参数、返回类型兼容
隐藏:
- 子类定义了和父类同名函数,不管参数是否相同,都会把父类同名函数隐藏掉。
一句话区分:
- 重载看同一作用域
- 重写看继承和虚函数
- 隐藏看名字遮蔽
10. STL 必考内容
STL 面试重点不是“会不会用”,而是“底层结构和复杂度”。
常见容器:
vector:动态数组,连续内存,随机访问快,尾插快。list:双向链表,插删快,随机访问慢。deque:双端队列,两端插入删除快。set/map:通常基于红黑树,自动有序。unordered_map/unordered_set:基于哈希表,平均查找快。
高频对比:
vector 和 list
vector查找和随机访问快。list中间插删快。vector内存连续,缓存友好。- 实际工程里
vector用得通常更多。
map 和 unordered_map
map有序,底层红黑树,复杂度O(logn)。unordered_map无序,底层哈希表,平均O(1),最坏O(n)。
11. vector 扩容机制
常问。
核心点:
vector底层是连续空间。- 空间不够时会重新申请更大内存。
- 把旧元素拷贝或移动到新空间。
- 释放旧空间。
代价:
- 扩容会导致迭代器、指针、引用失效。
优化:
- 提前
reserve(),减少扩容次数。
12. 智能指针
现代 C++ 非常重要。
常见三种:
unique_ptrshared_ptrweak_ptr
unique_ptr:
- 独占所有权。
- 不能拷贝,只能移动。
- 最轻量,优先使用。
shared_ptr:
- 共享所有权。
- 内部有引用计数。
- 最后一个持有者析构时释放资源。
weak_ptr:
- 弱引用,不增加引用计数。
- 用来解决
shared_ptr循环引用。
面试高频点:
为什么需要 weak_ptr?
因为两个 shared_ptr 相互引用时,引用计数永远不为 0,会内存泄漏。
13. RAII
这是 C++ 设计哲学的核心。
RAII:资源获取即初始化。
意思是:
- 资源在对象构造时获取
- 在析构时自动释放
好处:
- 自动管理资源
- 异常安全
- 降低泄漏风险
典型例子:
std::lock_guardstd::unique_ptr- 文件流对象
你可以把 RAII 理解为:不要把“释放资源”交给人脑记忆,交给对象生命周期。
14. 多线程常考点
C++ 多线程面试里最基础的是:
- 线程创建
- 互斥锁
- 条件变量
- 死锁
- 原子操作
互斥锁:
std::mutex- 防止多个线程同时修改共享资源
死锁产生条件常考:
- 互斥
- 请求与保持
- 不可剥夺
- 循环等待
避免方式:
- 固定加锁顺序
- 一次性申请所有锁
- 使用
std::lock
原子变量:
std::atomic- 适用于简单读写计数等场景
- 比互斥锁更轻,但不能替代所有同步
15. C++11 以后常见新特性
这些题也越来越常见。
auto
- 自动类型推导
范围 for
for (auto& x : v) {}
nullptr
- 替代
NULL - 类型安全
lambda
auto f = [](int a, int b){ return a + b; };
emplace_back
- 原地构造,减少临时对象
decltype
- 推导表达式类型
final / override
override表示明确重写final表示不能再继承或重写
16. 面试速记总结
如果你时间很紧,至少先背住下面这些核心句子:
new/delete比malloc/free多了构造析构。- 引用是别名,指针是地址变量。
- 有资源管理的类要考虑三法则/五法则。
- 多态靠虚函数实现,底层通常是虚表。
- 基类析构函数最好设为虚函数。
vector是连续内存,扩容会导致迭代器失效。map是红黑树,unordered_map是哈希表。unique_ptr独占,shared_ptr共享,weak_ptr破循环。std::move不移动,只做右值转换。- RAII 是 C++ 资源管理核心思想。
17. 怎么高效准备 C++ 八股
最后说点实用的。C++ 八股不是越背越多,而是要“成体系”。
推荐顺序:
- 先掌握指针、引用、内存模型
- 再掌握类、继承、多态、虚函数
- 再补拷贝控制、移动语义、智能指针
- 最后刷 STL 和多线程高频题
最有效的学习方法不是只看答案,而是每个知识点都问自己三件事:
- 它是什么
- 它解决什么问题
- 不用它会出什么问题
只要这三层能答出来,你就不是死背八股,而是真的会。


