快速掌握 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/freenew/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. inlinestaticconst

这三个词经常一起问。

inline

  • 建议编译器内联展开,减少函数调用开销。
  • 现代编译器是否真的展开,由编译器决定。

static

不同位置含义不同。

  • 修饰局部变量:生命周期变为整个程序运行期间,但作用域仍在函数内。
  • 修饰全局变量/函数:限制在当前文件可见。
  • 修饰类成员变量:属于类,不属于对象。
  • 修饰类成员函数:没有 this 指针,只能访问静态成员。

const

  • 表示只读。
  • 可修饰变量、指针、成员函数、返回值等。

成员函数后加 const

int get() const;

表示这个函数不修改对象状态。

9. 重载、重写、隐藏

面试喜欢放一起问。

重载 overload

  • 同一作用域
  • 同名函数
  • 参数列表不同

重写 override

  • 子类重写父类虚函数
  • 函数名、参数、返回类型兼容

隐藏:

  • 子类定义了和父类同名函数,不管参数是否相同,都会把父类同名函数隐藏掉。

一句话区分:

  • 重载看同一作用域
  • 重写看继承和虚函数
  • 隐藏看名字遮蔽

10. STL 必考内容

STL 面试重点不是“会不会用”,而是“底层结构和复杂度”。

常见容器:

  • vector:动态数组,连续内存,随机访问快,尾插快。
  • list:双向链表,插删快,随机访问慢。
  • deque:双端队列,两端插入删除快。
  • set / map:通常基于红黑树,自动有序。
  • unordered_map / unordered_set:基于哈希表,平均查找快。

高频对比:

vectorlist

  • vector 查找和随机访问快。
  • list 中间插删快。
  • vector 内存连续,缓存友好。
  • 实际工程里 vector 用得通常更多。

mapunordered_map

  • map 有序,底层红黑树,复杂度 O(logn)
  • unordered_map 无序,底层哈希表,平均 O(1),最坏 O(n)

11. vector 扩容机制

常问。

核心点:

  • vector 底层是连续空间。
  • 空间不够时会重新申请更大内存。
  • 把旧元素拷贝或移动到新空间。
  • 释放旧空间。

代价:

  • 扩容会导致迭代器、指针、引用失效。

优化:

  • 提前 reserve(),减少扩容次数。

12. 智能指针

现代 C++ 非常重要。

常见三种:

  • unique_ptr
  • shared_ptr
  • weak_ptr

unique_ptr

  • 独占所有权。
  • 不能拷贝,只能移动。
  • 最轻量,优先使用。

shared_ptr

  • 共享所有权。
  • 内部有引用计数。
  • 最后一个持有者析构时释放资源。

weak_ptr

  • 弱引用,不增加引用计数。
  • 用来解决 shared_ptr 循环引用。

面试高频点:

为什么需要 weak_ptr

因为两个 shared_ptr 相互引用时,引用计数永远不为 0,会内存泄漏。

13. RAII

这是 C++ 设计哲学的核心。

RAII:资源获取即初始化。

意思是:

  • 资源在对象构造时获取
  • 在析构时自动释放

好处:

  • 自动管理资源
  • 异常安全
  • 降低泄漏风险

典型例子:

  • std::lock_guard
  • std::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. 面试速记总结

如果你时间很紧,至少先背住下面这些核心句子:

  1. new/deletemalloc/free 多了构造析构。
  2. 引用是别名,指针是地址变量。
  3. 有资源管理的类要考虑三法则/五法则。
  4. 多态靠虚函数实现,底层通常是虚表。
  5. 基类析构函数最好设为虚函数。
  6. vector 是连续内存,扩容会导致迭代器失效。
  7. map 是红黑树,unordered_map 是哈希表。
  8. unique_ptr 独占,shared_ptr 共享,weak_ptr 破循环。
  9. std::move 不移动,只做右值转换。
  10. RAII 是 C++ 资源管理核心思想。

17. 怎么高效准备 C++ 八股

最后说点实用的。C++ 八股不是越背越多,而是要“成体系”。

推荐顺序:

  1. 先掌握指针、引用、内存模型
  2. 再掌握类、继承、多态、虚函数
  3. 再补拷贝控制、移动语义、智能指针
  4. 最后刷 STL 和多线程高频题

最有效的学习方法不是只看答案,而是每个知识点都问自己三件事:

  1. 它是什么
  2. 它解决什么问题
  3. 不用它会出什么问题

只要这三层能答出来,你就不是死背八股,而是真的会。

全部评论
还是你会总结呢
点赞 回复 分享
发布于 昨天 22:13 北京
写的很好呀,
点赞 回复 分享
发布于 昨天 22:13 北京

相关推荐

04-21 08:52
四川大学 Java
只爱喝白开水:别闹了92佬,别挑了,你随便一找就是我达不到的高度
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

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