本次全部对话完整知识点汇总


对话完整脉络:先拿到C++核心面试清单 → 深度深挖6大块重难点 → 进阶大厂专题(noexcept、4种强制转换、多线程‑内存序、forward、SFINAE),下面把从头到尾全部内容整理成一份完整复盘笔记

第一阶段:初始 C++ 核心题库(第一轮基础知识点)

面向对象、多态

  1. 多态:静态多态(编译期:函数重载、模板)、动态多态(运行期:虚函数 + 继承 + 基类指针/引用)
    • 底层原理:虚函数表 vtable、对象头部虚指针 vptr、晚绑定
  2. 基类虚析构:delete基类指针释放派生对象时,避免派生类资源泄漏
  3. 对象切片:派生对象赋值给栈上基类对象,派生独有成员被切掉;解决:用指针/引用接收
  4. override:校验虚函数重写签名;final:禁止类继承 / 禁止虚函数重写

RAII、内存管理

  1. RAII(资源获取即初始化):资源生命周期绑定局部对象生命周期;构造申请资源,析构自动释放;异常安全,防泄漏。
  2. new/delete vs malloc/free
    • malloc/free:C库函数,只处理原始内存,不调用构造/析构
    • new/delete:C++运算符,分配内存+调用构造;释放前调用析构;new失败抛bad_alloc
    • 禁止混用
  3. new[] / delete[]配对原则,数组隐藏计数,混用delete造成未定义行为

智能指针

  1. unique_ptr:独占所有权、禁止拷贝,仅移动;无引用计数
  2. shared_ptr:共享所有权;引用计数use_count;多线程计数器原子、对象操作非线程安全
  3. weak_ptr:弱引用,不增加强计数,解决shared_ptr循环引用

右值引用、移动语义

  1. 左值、右值区分;std::move仅类型转换,不移动数据
  2. 移动构造:转移堆资源所有权,减少深拷贝开销

const / static

  1. const各种修饰场景:常量变量、常量指针、指针常量、const成员函数
  2. static:局部静态变量、类静态成员变量、静态成员函数(无this指针)

STL容器

  1. vector底层连续数组、扩容机制(1.5‑2倍)、迭代器失效
  2. map(红黑树有序 O(logn)) vs unordered_map(哈希表无序,平均O(1))
  3. vector / list迭代器失效区别

继承

  1. 三种继承:public / protected / private继承访问权限变化
  2. 菱形继承问题,虚继承virtual解决方案

C++11 Lambda

捕获方式[]、[=]、[&]、mutable关键字


第二阶段:深度深挖专题1(你指定深入讲解)

1.new[] / delete[]深度

  • new[]会在返回指针前面隐藏存储数组元素个数N
  • delete[]逆序调用析构
  • new[] + delete(不带[]):只析构第一个对象,内存泄漏+未定义行为
  • 内置类型int无析构混用侥幸不出错,依然UB

2.shared_ptr循环引用 + weak_ptr完整解析

  • shared_ptr结构:对象指针 + 控制块(use_count、weak_count)
  • 循环引用成因:两个对象互相保存shared_ptr,use_count永远不能归零,内存泄漏
  • weak_ptr:弱引用,只修改weak_count,不增加use_count;lock()升级shared_ptr;expired()判断对象是否销毁
  • 解决方案:双向依赖一边shared_ptr拥有所有权,另一边weak_ptr观察者

3.std::move、移动构造、移动赋值

  1. std::move源码本质:static_cast转换成右值引用,无任何资源搬运
  2. 左值、纯右值、将亡值
  3. 移动构造接管堆资源,源对象置空,防止二次释放
  4. noexcept至关重要:vector扩容时,如果移动构造没有noexcept,容器放弃移动,降级拷贝构造
  5. 被move后的对象处于有效但未指定状态

4.菱形继承(钻石继承)详解

  1. 普通菱形继承:产生两份父类副本、二义性、内存冗余
  2. virtual虚继承:生成唯一一份公共父类
  3. 底层内存布局:vbptr虚基指针,虚基表存放偏移量;虚基类放在内存末尾
  4. 构造规则:最远派生类负责虚基类的构造函数

5.大厂进阶面试题第一波

虚函数表和虚基表区别;构造函数不能为虚函数原因;空类大小1字节;volatile不能保证线程安全;RVO/NRVO返回值优化;右值引用延长临时生命周期;完美转发std::forward;迭代器失效;SFINAE概念


第三阶段:深度深挖专题2 noexcept + 4种强制转换

1. noexcept

  1. C++11异常说明符,函数承诺不会抛出异常;条件式noexcept(表达式)
  2. 契约而非强制;noexcept函数抛异常 → terminate()直接终止程序
  3. 核心作用:影响STL vector扩容是否选用移动构造
  4. noexcept运算符编译期检测表达式是否可能抛异常
  5. 虚函数重写时noexcept必须兼容

2. 四种强制转换

  1. static_cast:编译期检查,良性转换,数值转换,向上继承转换;向下转型不安全,无运行校验
  2. dynamic_cast:运行时检查、依赖RTTI、类必须含有虚函数;指针失败返回nullptr,引用失败抛异常;支持横向(兄弟类)转换
  3. const_cast:唯一修改const/volatile限定符;不能修改原生const对象(UB)
  4. reinterpret_cast:二进制比特原样重解释;指针整数互转,底层开发使用,可移植性差
  5. C风格强制转换缺点:依次尝试多种转换,意图模糊,现代C++不推荐

第四阶段:深度深挖专题3 多线程原子、内存序、forward、SFINAE

1.寄存器、volatile、std::mutex、std::atomic

  1. 寄存器:CPU高速缓存;编译器优化将变量缓存寄存器,线程看不见内存上新值
  2. volatile:禁止编译器优化缓存;不能保证原子性,不能阻止CPU指令重排,不可用于线程同步
  3. std::mutex互斥锁:阻塞悲观锁;保证原子性、可见性、有序性;线程休眠‑内核切换开销大;保护一段临界区代码
  4. std::atomic原子变量:硬件原子指令实现无锁并发;保证单变量原子性;性能高于锁

2.C++11 memory_order 六大内存序(控制编译器+CPU指令重排)

  1. memory_order_relaxed:宽松序;仅原子性;无顺序屏障,适合计数器
  2. memory_order_release:store写屏障,前面指令不能重排到写之后
  3. memory_order_acquire:load读屏障,后面指令不能重排到读之前;acquire‑release配对建立happen‑before同步关系
  4. memory_order_acq_rel:读写双向屏障,用于fetch_add等读‑改‑写原子操作
  5. memory_order_consume:弱化acquire,现已废弃
  6. memory_order_seq_cst:顺序一致性,atomic默认内存序;最强全局屏障,开销最高

3.std::forward完美转发 & 万能引用、引用折叠

  1. 万能引用:模板T&&≠右值引用;支持绑定左值/右值;引用折叠规则
  2. 具名变量永远为左值;右值传入模板函数内部后丢失右值属性
  3. std::forward(arg):保留参数原始左/右值属性,原样转发
  4. move vs forward对比:move无条件转为右值;forward按需转换,用于模板转发场景

4.SFINAE

全称 Substitution Failure Is Not An Error(替换失败不是错误)

  1. 生效时机:模板参数替换阶段;非法代码不会报编译错误,直接舍弃当前重载
  2. 函数体内部报错不属于SFINAE
  3. 用途:C++17前类型萃取检测类成员;C++20优先concept替代SFINAE

全对话高频易混考点对照表(面试必背)

  1. shared_ptr循环引用 → weak_ptr解决
  2. 菱形继承二义性 → virtual虚继承
  3. new[] ↔ delete[]严格配对
  4. std::move:仅转换;std::forward:完美转发
  5. volatile ≠ 线程安全;atomic提供原子性;mutex阻塞锁保护大片逻辑
  6. 移动构造不加noexcept → vector扩容放弃移动,降级拷贝
  7. static_cast向下转型快不安全;dynamic_cast向下转型安全带RTTI开销

如果你需要,我可以把这份完整内容导出成可打印精简背诵版。


2 9 月, 2026Garfield God学习笔记阅读 2 次

0 条回复

还没有留言,来说点什么吧。

留言