C++权威八股文总结:面试高频知识点一次讲透

面试里问 C++,从来不是在考你会不会写个 for 循环,也不是只想听你背“封装、继承、多态”。真正想看的,是你对 对象模型、生命周期、资源管理、泛型能力、STL 使用习惯、现代 C++ 语义 到底理解到什么程度。

先说结论:C++ 八股的核心,不是零散知识点,而是四条主线

  1. 对象是怎么创建、销毁、布局和调用的
  2. 资源是怎么管理的,尤其是内存、所有权、拷贝与移动
  3. 泛型和 STL 是怎么帮你写出更安全、更高效代码的
  4. 现代 C++ 语义你到底是“听过”,还是“真的会用”

一、对象模型:C++ 的根基在这里

C++ 和很多语言最大的区别之一,就是它离内存和对象布局非常近。

面试里这里常问的,不是“类是什么”,而是:

  • 对象在内存里怎么放
  • 成员变量和成员函数分别属于什么
  • this 指针是什么
  • 虚函数、多态到底怎么实现
  • 构造、析构、拷贝、移动这些操作什么时候发生

最基本的结论要先记住:

  • 成员变量属于对象
  • 成员函数不属于某个对象实例本身,代码段里只有一份
  • 非静态成员函数调用时默认带一个 this 指针
  • 静态成员变量属于类,不属于某个对象
  • 静态成员函数没有 this 指针

如果连这条线都不清楚,后面很多题会越答越虚。

核心大厂开发面试题以及基础八股文资料汇总:

https://www.nowcoder.com/creation/manager/columnDetail/Mq7XWW

二、构造、析构、拷贝、移动:生命周期问题是高频核心

C++ 面试非常喜欢围绕对象生命周期追问,因为这直接决定你会不会写出有 bug 的代码。

这里最重要的是四组概念:

  • 构造函数和析构函数
  • 拷贝构造和拷贝赋值
  • 移动构造和移动赋值
  • Rule of Three / Five / Zero

1. 构造和析构

构造函数负责对象初始化,析构函数负责对象销毁时释放资源。

如果类里持有堆内存、文件句柄、锁、socket 这类资源,析构函数就不能乱写。

要点:

  • 构造函数可以重载,析构函数不能重载
  • 析构函数一般不能带参数
  • 基类析构函数如果可能通过基类指针删除子类对象,必须写成虚析构函数

这句是面试里的标准送分点:

“多态基类通常要有虚析构函数,否则通过基类指针释放派生类对象会导致析构不完整。”

2. 拷贝语义

拷贝构造发生在“用一个已有对象初始化另一个对象”时。

拷贝赋值发生在“两个已经存在的对象之间赋值”时。

最常考的坑是浅拷贝和深拷贝。

如果类内部直接管理裸指针,那么默认拷贝往往只是地址复制,多个对象会指向同一块内存,最终导致:

  • 重复释放
  • 悬空指针
  • 数据互相污染

所以一旦类自己管理资源,就必须认真考虑拷贝行为。

3. 移动语义

C++11 之后,移动语义几乎是必考点。

它解决的问题很明确:

有些对象不需要真的“复制资源”,只需要把资源所有权转走。

典型场景:

  • 返回大对象
  • 容器扩容搬迁元素
  • 临时对象传递
  • 智能指针转移所有权

这里最关键的几个点:

  • 左值有名字、可取地址、可重复使用
  • 右值通常是临时对象,适合“被搬走”
  • std::move 本身不移动,它只是把对象转换成右值引用
  • 真正发生移动的是移动构造或移动赋值函数

面试如果问“移动语义的意义”,一个很稳的回答是:

减少不必要的深拷贝,提高性能,同时让资源所有权转移更明确。

三、引用、指针、const:这是基本功,不是小题

这一块几乎每场 C++ 面试都会问。

1. 引用和指针的区别

你至少要说清这些:

  • 引用必须初始化,指针不一定
  • 引用一旦绑定,通常不能改绑
  • 指针是变量,存地址;引用更像别名
  • 指针可以为 nullptr,引用通常不允许为空语义

但真正加分的,不是背这些差异,而是知道什么时候用谁。

一般来说:

  • 参数传递优先考虑 const T&
  • 需要表达“可为空”时更适合指针
  • 需要表达“对象别名、必然存在”时更适合引用

2. const 的常见考法

const 高频得不能再高频了,常见问题包括:

  • const int *p
  • int * const p
  • const int * const p
  • const 修饰成员函数是什么意思
  • const 对象能调用哪些成员函数

一句话记忆:

  • const 修饰谁,谁就不能通过这个名字被改
  • const 成员函数表示不修改对象的逻辑状态
  • mutable 可以突破这种只读限制,用于缓存等场景

四、虚函数、多态、vptr/vtable:面试最爱深挖的地方

如果说 C++ 面试最能区分“会背”和“真懂”的地方,虚函数绝对排前列。

1. 多态的本质

多态分静态多态和动态多态。

  • 静态多态:函数重载、模板
  • 动态多态:虚函数 + 继承 + 基类指针/引用调用

动态多态成立的条件要说全:

  1. 要有继承关系
  2. 基类函数要声明为 virtual
  3. 必须通过基类指针或引用调用重写后的函数

2. 虚函数如何实现

核心点:

  • 含虚函数的类通常会有虚函数表 vtable
  • 对象里通常会有虚表指针 vptr
  • 运行时通过 vptr 找到实际类型对应的虚函数表,从而调用正确函数

这就是“动态绑定”的本质。

3. 纯虚函数和抽象类

  • 纯虚函数写法:virtual void func() = 0;
  • 含纯虚函数的类是抽象类,不能实例化
  • 派生类如果不重写纯虚函数,自己也还是抽象类

这类题不难,但很高频。

五、new/delete、malloc/free、智能指针:资源管理是现代 C++ 面试重点

1. new/deletemalloc/free 的区别

标准回答至少包括:

  • new/delete 是 C++ 运算符,malloc/free 是 C 库函数
  • new 会调用构造函数,delete 会调用析构函数
  • malloc 只分配原始内存,free 只释放原始内存
  • new 返回对应类型指针,malloc 返回 void*

真正的面试意图其实是看你有没有资源管理意识。

现代 C++ 项目里,能不用裸 new 就尽量不用。

2. 智能指针

这是现代 C++ 面试的重点区。

最常见三个:

  • std::unique_ptr
  • std::shared_ptr
  • std::weak_ptr

要点非常清楚:

  • unique_ptr 独占所有权,不能拷贝,可以移动
  • shared_ptr 引用计数,共享所有权
  • weak_ptr 不增加引用计数,用来观察资源,常用于打破循环引用

高频追问:

  • shared_ptr 为什么会有循环引用问题
  • make_shared 和直接 new 有什么差异
  • unique_ptr 为什么更轻量
  • 智能指针能不能完全替代裸指针

一句话总结这部分最容易得分:

现代 C++ 的核心思想之一,就是把资源管理从“人肉记忆”变成“对象生命周期自动托管”。

六、STL 必须会,但不能只会名字

很多人 STL 只会背 vector/list/map/unordered_map 的区别,这肯定不够。

面试真正常问的是:

  • 底层数据结构
  • 插入删除查找复杂度
  • 迭代器失效
  • 什么时候选哪个容器

1. vector

高频中的高频:

  • 底层连续内存
  • 支持随机访问
  • 尾插效率高
  • 中间插入删除可能搬移大量元素
  • 扩容会引发重新分配,迭代器、指针、引用可能失效

2. list

  • 双向链表
  • 任意位置插入删除方便
  • 不支持随机访问
  • 节点分散,缓存局部性差

3. mapunordered_map

  • map 通常基于红黑树,有序,复杂度稳定
  • unordered_map 基于哈希表,无序,平均查找快,但最坏可能退化

真正面试里不要只说“一个有序一个无序”,太薄了。

七、模板、泛型、inline、constexpr:现代 C++ 语义不能缺

1. 模板

模板的核心价值不是“少写代码”,而是 把算法和类型解耦

高频点:

  • 函数模板和类模板
  • 模板实例化
  • 模板特化与偏特化
  • 为什么模板实现通常放头文件

最后一个很常问,答案是:

模板需要在编译期看到完整定义,才能完成实例化。

2. inline

inline 现在不只是“建议内联展开”,更重要的一层意义是:

  • 允许函数在多个翻译单元中定义而不违反 ODR
  • 类内定义成员函数通常隐式具备 inline 属性

3. constexpr

constexpr 是现代 C++ 面试里越来越常见的点。

你至少要知道:

  • 它强调编译期可求值
  • 可用于常量表达式、编译期优化
  • 比传统宏和 const 更类型安全、更现代

八、多线程基础:不会太深,但越来越常问

如果岗位偏后端、客户端、基础架构,C++ 并发几乎绕不过。即使是嵌入式 Linux 岗,也常会问到。

高频点包括:

  • thread
  • mutex
  • lock_guard
  • unique_lock
  • condition_variable
  • atomic

这里面最容易被追问的是:

  • 为什么会有竞态条件
  • 互斥锁和原子操作的区别
  • 死锁怎么产生,怎么避免
  • lock_guardunique_lock 的区别

不用一上来讲内存序讲到飞起,但基本概念一定要稳。

九、面试中什么算“会 C++”,什么不算

如果你想知道面试官怎么看“C++ 基础扎实”,标准通常不是你背了多少定义,而是下面这几件事。

算会的表现:

  • 能把对象生命周期讲清楚
  • 能解释拷贝、移动、所有权
  • 知道虚函数、多态背后的运行机制
  • 能说清 STL 容器选型依据
  • 知道现代 C++ 为什么提倡 RAII 和智能指针
  • 遇到问题会从语义、性能、资源、安全性一起分析

不算会的表现:

  • 只会背“封装继承多态”
  • 只会说“智能指针防内存泄漏”
  • 只会说“vector 底层是数组”
  • 分不清拷贝构造和赋值
  • 分不清左值右值、移动和转发
  • 说不清为什么基类析构要设为虚函数

十、适合面试前突击的高频题清单

  1. C 和 C++ 最核心的区别是什么
  2. 引用和指针的区别是什么
  3. const 有哪些典型用法
  4. static 在 C++ 中有哪些作用
  5. this 指针是什么
  6. 构造函数能不能是虚函数
  7. 析构函数为什么常常要写成虚函数
  8. 拷贝构造和拷贝赋值的区别是什么
  9. 什么是深拷贝,什么是浅拷贝
  10. 什么是移动语义
  11. std::move 到底做了什么
  12. 左值、右值、右值引用怎么理解
  13. 什么是完美转发
  14. 虚函数是怎么实现动态多态的
  15. 纯虚函数和抽象类是什么
  16. new/deletemalloc/free 的区别是什么
  17. unique_ptrshared_ptrweak_ptr 的区别是什么
  18. shared_ptr 为什么会循环引用
  19. vector 扩容会发生什么
  20. 哪些容器会发生迭代器失效
  21. mapunordered_map 如何选择
  22. 模板为什么通常写在头文件里
  23. inlineconstexpr 分别解决什么问题
  24. mutexatomic 的适用场景有什么不同
  25. RAII 为什么是现代 C++ 的核心思想之一

结尾

C++ 八股真正难的地方,从来不是知识点多,而是它每一个点都能往下深挖,而且彼此之间是连着的。你要是真的想把 C++ 面试准备到位,不要只背单题,而要围绕这几条主线去复习:对象模型、生命周期、资源管理、泛型与 STL、现代语义

把这几条线吃透,很多题你不用死记,也能自己顺着逻辑答出来。

全部评论
点赞 回复 分享
发布于 今天 11:19 河南
很少在牛客看到技术类的文章
点赞 回复 分享
发布于 今天 11:16 安徽

相关推荐

评论
2
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务