1、C++ 基础知识笔记 C 是一门庞大且复杂的语言。为了帮你高效复习我将 C 基础知识体系化为7 大核心模块。这份清单涵盖了从语法基础到现代 CC11/14/17/20的关键特性适合作为面试准备或项目开发的自查表。1. 基础语法与数据类型这是 C 的基石重点在于理解“底层”行为。基本类型int,float/double,char,bool,void。注意各类型在不同平台下的字节大小及取值范围。类型修饰符const只读、volatile防优化、signed/unsigned、static静态存储期/局部可见性。引用 vs 指针指针可为空、可重新赋值、有二级指针、需手动管理内存。引用必须初始化、不可更改绑定、无空引用、更安全。类型转换C风格(type)value不安全。C风格static_cast编译期安全转换、dynamic_cast运行时多态转换、const_cast去const、reinterpret_cast二进制重解释危险。作用域与生命周期全局、局部、块级作用域栈对象自动销毁 vs 堆对象手动销毁。2. 面向对象编程 (OOP)C 的核心范式面试和工程中的重中之重。封装public/protected/private访问控制friend友元机制。继承单继承、多继承注意菱形继承问题及虚继承virtual解决方案。多态编译期多态函数重载、运算符重载、模板。运行期多态虚函数 (virtual)、纯虚函数 (0)、抽象类。⚠️关键点基类析构函数必须声明为virtual否则通过基类指针删除派生类对象会导致未定义行为内存泄漏。构造与析构构造函数初始化列表 vs 函数体内赋值性能差异。拷贝构造函数、移动构造函数。拷贝赋值运算符、移动赋值运算符。Rule of Five / Rule of Zero如果定义了析构/拷贝/移动中的任何一个通常需要定义全部五个或者使用智能容器让编译器自动生成。2.1 多态多态的实现是基于虚函数virtualC 的虚函数表Virtual Table简称 vtable机制是实现运行时多态Runtime Polymorphism的核心底层技术。当你在 C 中使用virtual关键字时编译器通常会自动生成 vtable 和相关的指针来支持动态绑定。以下是该机制的深度解析1. 核心概念vtable (虚函数表): 本质上是一个静态数组或类似结构存储在程序的只读数据段中。每个包含虚函数的类都有自己独立的一张 vtable。表中存储了该类所有虚函数的函数指针。vptr (虚表指针): 一个隐藏的指针成员被编译器自动插入到每个包含虚函数的类的对象实例中。它指向该对象所属类的 vtable。2. 内存布局模型类的 vtable 结构假设有一个基类Base和一个派生类DerivedclassBase{public:virtualvoidfuncA();virtualvoidfuncB();voidnonVirtual();// 不在vtable中};classDerived:publicBase{public:voidfuncA()override;// 重写virtualvoidfuncC();// 新增虚函数};内存中的 vtable 大致如下Base::vtableDerived::vtable[0] Base::funcA[0] Derived::funcA (被覆盖)[1] Base::funcB[1] Base::funcB (继承)[2] Derived::funcC (新增)关键点Derived的 vtable 中funcA的位置与Base中相同但指向的是Derived::funcA的实现。这保证了通过基类指针调用时能正确索引。对象的内存布局当你创建Derived d;时对象内存通常如下以单继承为例------------------ | vptr | ----- Derived::vtable ------------------ | Base 成员变量 | ------------------ | Derived 成员变量 | ------------------3. 虚函数调用过程当你执行basePtr-funcA()时CPU 实际执行的步骤是从对象起始地址读取vptr。通过vptr找到对应的vtable。根据funcA在表中的固定偏移量offset取出函数指针。跳转到该函数指针指向的地址执行代码。伪代码表示// basePtr-funcA() 等价于(*(basePtr-vptr)[OFFSET_OF_funcA])(basePtr);4. 复杂场景处理多重继承 (Multiple Inheritance)如果一个类继承了多个带虚函数的基类对象中会有多个 vptr分别指向不同基类子对象的 vtable。------------------ | vptr (Base1) | ----- Base1_vtable / Derived_vtable_for_Base1 ------------------ | Base1 成员 | ------------------ | vptr (Base2) | ----- Base2_vtable / Derived_vtable_for_Base2 (可能带偏移调整) ------------------ | Base2 成员 | ------------------ | Derived 自有成员 | ------------------当通过Base2*指针调用虚函数时编译器可能需要使用Thunk 技术来调整this指针使其正确指向Derived对象的完整起始地址。虚继承 (Virtual Inheritance)为了解决菱形继承问题虚继承引入了额外的间接层。vtable 中不仅包含虚函数指针还可能包含虚基类偏移量vbptr/vbtable用于在运行时定位共享的虚基类子对象。这使得虚继承的对象布局和调用开销比单继承/多重继承更大。5. 性能与开销方面说明空间开销每个含虚函数的类多一张 vtable每个对象多一个 vptr通常 8 字节/64位系统时间开销每次虚函数调用增加 1-2 次内存间接寻址读 vptr → 读 vtable → 跳转内联优化虚函数通常无法内联因为编译器在编译期不知道实际调用的目标函数除非能静态推断出具体类型缓存友好性vtable 访问可能导致 cache miss尤其在大量不同类型对象混合调用时6. 重要注意事项非标准规定: vtable 是编译器的实现细节C 标准并未规定必须使用 vtable尽管几乎所有主流编译器都这么做。ABI 兼容性: 不同编译器甚至同一编译器的不同版本/选项生成的 vtable 布局可能不同这就是为什么跨编译器链接 C 代码经常出问题。Itanium C ABI 试图标准化这一布局。构造/析构期间: 在构造函数和析构函数执行期间vptr 会逐步更新。不要在构造/析构函数中调用虚函数因为此时 vptr 可能尚未指向最终派生类的 vtable导致行为不符合预期。RTTI 关联:typeid和dynamic_cast通常也依赖 vtable 中的额外信息如 typeinfo 指针来实现运行时类型识别。总结vtable 机制是用空间换时间的经典设计通过在对象中嵌入指针、在类中维护函数指针表将“调用哪个函数”的决策从编译期推迟到运行期从而实现了面向对象编程中最核心的多态特性。理解它有助于写出更高效的 C 代码并在调试复杂继承问题时快速定位根源。3. STL 标准模板库不要重复造轮子熟练掌握 STL 是 C 工程师的基本素养。分类常用组件关键知识点容器vector,deque,list,array内存布局、扩容机制vector 1.5x/2x、迭代器失效条件关联容器map/set,unordered_map/set红黑树 vs 哈希表、查找复杂度 O(logN) vs O(1)适配器stack,queue,priority_queue底层容器选择、优先队列的比较器算法sort,find,transform,accumulateLambda 配合、自定义比较器、时间复杂度迭代器Input/Output/Forward/Bidirectional/RandomAccess迭代器类别决定可用算法⚠️避坑指南永远不要在遍历容器时直接erase应使用erase-remove惯用法或 C20 的std::erase_if。4. 内存管理C 区别于其他高级语言的核心难点。栈 vs 堆栈由编译器管理快、小堆由程序员管理慢、大。原始指针new/delete,new[]/delete[]必须配对使用。智能指针现代 C 必用std::unique_ptr独占所有权零开销推荐默认使用。std::shared_ptr引用计数共享所有权注意循环引用问题。std::weak_ptr解决shared_ptr循环引用不增加引用计数。RAII资源获取即初始化。将资源生命周期绑定到对象生命周期确保异常安全。内存对齐alignof,alignas结构体填充规则。5. 模板与泛型编程C 最强大的特性之一也是编译错误的重灾区。函数模板 类模板模板参数推导、特化全特化/偏特化。SFINAE“Substitution Failure Is Not An Error”std::enable_if。Concepts (C20)约束模板参数替代 SFINAE大幅提升可读性和错误信息质量。可变参数模板templatetypename... Args完美转发std::forward。编译期计算constexpr,consteval(C20),if constexpr。6. 现代 C 核心特性 (C11 ~ C20)如果你还在写 C98 风格的代码请务必更新知识库。C11:auto,nullptr, 范围for循环, Lambda,std::move, 右值引用,override/final,enum class,std::thread。C14:泛型Lambda (auto参数),std::make_unique, 返回值推导。C17:std::optional/variant/any, 结构化绑定auto [x,y] ...,if constexpr, 并行算法,std::string_view。C20:Modules(取代头文件),Coroutines(协程),Ranges(惰性求值管道),Concepts,std::format, 三路比较。C23/26 展望std::print,std::expected, 反射提案等。7. 并发编程线程管理std::thread,std::jthread(C20, 自动join)。同步原语std::mutex,std::lock_guard,std::unique_lock,std::scoped_lock(C17, 防死锁)。条件变量std::condition_variable注意虚假唤醒。原子操作std::atomic内存序 (memory_order)。异步std::future/promise,std::async。