C++ 核心知识点全解

📅 发布时间:2026/7/9 6:33:08 👁️ 浏览次数:
C++ 核心知识点全解
C 核心知识点全解一、基础语法与类型系统1. 基本数据类型与大小2. 类型限定符3. 初始化方式4. 左值与右值5. 自增自减6. 流程控制7. 函数重点7.1 默认参数7.2 函数重载7.3 内联函数 inline二、指针、引用、内存结构1. 指针2. 引用 3. C 内存五大区4. new/delete 与 malloc/free三、面向对象 OOP1. 类与访问控制2. 六大特殊成员函数C113. 构造函数4. 析构函数5. 拷贝构造 浅/深拷贝6. 拷贝赋值运算符7. 移动语义C118. this 指针四、继承与多态1. 继承方式2. 构造析构顺序3. 同名隐藏4. 运行期多态5. 纯虚函数与抽象类6. 虚析构7. 菱形继承与虚继承五、模板与泛型编程1. 函数模板2. 类模板3. 模板特化4. 可变参数模板C11六、现代 C 核心特性C11/14/171. auto 类型推导2. decltype3. Lambda 表达式4. 智能指针memory5. 其他常用现代特性七、STL 标准模板库1. 容器分类2. 常用容器选型3. 迭代器4. 常用算法algorithm八、异常处理九、友元、运算符重载1. 友元2. 运算符重载十、常用工程惯用法一、基础语法与类型系统1. 基本数据类型与大小C 标准只规定最小范围具体大小由平台决定。常见 32/64 位平台典型大小类型典型字节数说明bool1true / falsechar1字符 / 小整数short2短整型int4整型常用long4 / 8长整型long long8长长整型float4单精度浮点double8双精度浮点常用long double8 / 16扩展精度无符号类型unsigned char、unsigned int等只存非负数。字面值后缀10u/10U→ unsigned10l/10L→ long10ll/10LL→ long long3.14f→ float2. 类型限定符const只读变量必须初始化之后不能赋值。constinta10;a20;// 错误constexprC11编译期可求值性能更好。constexprintsquare(intx){returnx*x;}intarr[square(5)];// 合法编译期确定大小volatile告诉编译器不要优化每次必须从内存读多用于硬件/多线程。register建议放入寄存器现代编译器基本自动优化。3. 初始化方式C11 推荐统一使用列表初始化更安全。inta10;// 拷贝初始化intb(10);// 直接初始化intc{10};// 列表初始化推荐intd{10};// 同上列表初始化禁止窄化转换intx{3.14};// 编译报错防止精度丢失4. 左值与右值左值可以放在左边有内存地址可以被多次使用。inta10;a20;// a 是左值右值临时值不能取地址用完即销毁。10;// 右值ab;// 表达式结果是右值5. 自增自减前置i先自增返回自身左值效率更高。后置i先复制旧值再自增返回旧值右值。inti0;couti;// 输出 1couti;// 输出 1i 变为 26. 流程控制范围 forC11遍历容器/数组更简洁。vectorintv{1,2,3};for(intx:v){...}// 拷贝for(intx:v){...}// 引用可修改for(constintx:v){...}// 只读高效switch只能匹配整型/枚举常量case 默认穿透必须加break。7. 函数重点7.1 默认参数必须从右往左连续设置。voidf(inta,intb1,intc2);// 正确voidf(inta1,intb,intc);// 错误声明时写默认参数实现时不要重复写。7.2 函数重载同一作用域内函数名相同参数列表不同个数/类型/顺序。intadd(inta,intb);doubleadd(doublea,doubleb);// 重载返回值不同不能构成重载。7.3 内联函数 inline建议编译器将函数体展开到调用处减少函数调用开销。适合短小、频繁调用的函数。类内定义的函数默认 inline。二、指针、引用、内存结构1. 指针指针是存地址的变量。inta10;int*pa;// p 存 a 的地址*p20;// 解引用修改 a空指针nullptrC11类型安全优于NULL。野指针指向无效/已释放内存使用会崩溃或未定义行为。悬空指针delete后未置nullptr。指针运算p1以指向类型大小为单位只在同一数组内合法。2. 引用 引用是变量别名与原对象共用同一块内存。inta10;intra;r20;// a 也变成 20特性必须初始化不能“空引用”。不能重新绑定到另一个变量。编译器底层通常用指针实现但使用更安全。const 引用可以绑定临时对象右值constintr10;// 合法常用场景函数参数避免大对象拷贝。函数返回成员引用注意生命周期。3. C 内存五大区栈 stack局部变量、函数参数、返回地址。自动分配/释放连续、小、极快。递归过深、超大局部数组会栈溢出。堆 heapnew/malloc分配手动管理。空间大、随机、较慢。忘记delete→内存泄漏。全局/静态区全局变量、static变量。程序启动创建结束释放默认初始化为 0。常量区字符串常量、const全局数据。只读修改会崩溃。代码区存放可执行指令只读共享。4. new/delete 与 malloc/freenew/delete是运算符会调用构造/析构函数。malloc/free是库函数只分配/释放裸内存。必须配对new↔deletenew[]↔delete[]常见错误用free释放new出来的内存。用delete释放malloc出来的内存。重复释放、释放野指针。三、面向对象 OOP1. 类与访问控制class默认privatestruct默认public。访问权限private仅本类/友元可访问。protected本类/友元/子类可访问。public全局可访问。2. 六大特殊成员函数C11编译器会自动生成但若你手写其中一部分另一些可能被删除。默认构造析构函数拷贝构造拷贝赋值移动构造移动赋值3. 构造函数与类同名无返回值创建对象时自动调用。初始化列表比函数体内赋值更早、效率更高。Person(string n,inta):name(std::move(n)),age(a){}必须用初始化列表的场景const成员引用成员基类无默认构造成员对象无默认构造4. 析构函数~类名()无参无返回不可重载。对象销毁时自动调用用于释放资源堆内存、文件、socket 等。若类中有指针成员通常需要手写析构防止内存泄漏。多态基类的析构函数建议声明为 virtual否则可能只调用基类析构造成泄漏。5. 拷贝构造 浅/深拷贝拷贝构造用已有对象初始化新对象。Person(constPersonother);默认拷贝构造是浅拷贝只复制成员值。浅拷贝问题多个对象指向同一块堆内存析构时重复 delete崩溃。深拷贝重新分配内存并复制内容需手动实现。6. 拷贝赋值运算符Personoperator(constPersonother);经典三步写法防止自赋值if (this other) return *this;释放当前对象资源深拷贝资源返回*this支持链式赋值7. 移动语义C11右值引用T专门绑定临时对象。移动构造 / 移动赋值转移资源所有权不拷贝数据效率极高。Person(Personother)noexcept;Personoperator(Personother)noexcept;std::move将左值强制转为右值引用本身不移动任何数据。标准库容器默认优先使用移动操作。8. this 指针指向当前对象本身类型为类名* const。用于区分成员与参数重名voidsetAge(intage){this-ageage;}链式调用返回*thisPersonsetName(string n){namestd::move(n);return*this;}p.setName(Alice).setAge(20);四、继承与多态1. 继承方式class子类:继承方式 父类{...};public继承最常用基类权限基本保留。protected继承基类public变protected。private继承基类所有成员变private。2. 构造析构顺序构造基类构造 → 成员对象构造 → 自身构造析构自身析构 → 成员对象析构 → 基类析构子类必须在初始化列表中初始化基类如果基类没有默认构造。3. 同名隐藏子类定义与基类同名函数会隐藏基类所有同名重载版本。如需在子类中使用基类重载版本usingBase::func;4. 运行期多态多态 接口统一实现不同。满足三条件公有继承基类函数为virtual 虚函数基类指针/引用指向子类对象底层实现虚表 vtable 虚指针 vptr。重写子类重新实现虚函数函数签名必须完全一致。override显式标记重写编译器检查拼写/签名错误强烈推荐。voidshow()override;final修饰类禁止被继承。修饰虚函数禁止被重写。5. 纯虚函数与抽象类virtualvoiddraw()0;包含纯虚函数的类称为抽象类不能实例化。子类必须实现所有纯虚函数才能实例化用于定义接口。6. 虚析构基类析构声明为virtual则通过基指针删除子类对象时会多态调用子类析构。否则只调用基类析构子类资源泄漏。classBase{public:virtual~Base()default;};7. 菱形继承与虚继承问题顶层基类被多份继承数据冗余、访问二义性。解决方案虚继承classB:virtualpublicA{...};classC:virtualpublicA{...};虚继承下由最派生类负责初始化公共基类。五、模板与泛型编程1. 函数模板templatetypenameTTadd(T a,T b){returnab;}编译期根据实参类型生成对应版本实例化。支持多个类型参数、非类型模板参数整数常量。templatetypenameT,intNTsum(T(arr)[N]){...}2. 类模板templateclassTclassStack{vectorTdata;public:voidpush(constTx);};实例化Stackint st;类模板成员函数通常全写在头文件/同文件否则链接时可能找不到实例。3. 模板特化全特化对某一特定类型完全重写。templateclassStackint{...};偏特化只适用于类模板对一类类型如指针特殊处理。templateclassTclassStackT*{...};4. 可变参数模板C11templateclass...Argsvoidprint(Args...args){...}...表示参数包。展开方式递归、逗号表达式、折叠表达式C17。templateclass...Argsautosum(Args...args){return(args...);// 一元右折叠}六、现代 C 核心特性C11/14/171. auto 类型推导从初始化表达式自动推导类型。会丢弃顶层 const、引用如需保留constautoxy;典型场景迭代器、复杂模板、lambda。vectorintv;autoitv.begin();2. decltype推导表达式类型不丢弃 const/引用。常用于返回类型后置、模板元编程。inta10;decltype(a)b20;// intdecltype((a))ra;// int3. Lambda 表达式[capture](params)mutable-ret{body}捕获列表[]不捕获[]值捕获外部变量[]引用捕获[this]捕获当前对象指针mutable允许修改值捕获的副本。无捕获 lambda 可隐式转为函数指针。常用于 STL 算法、回调、线程函数。sort(v.begin(),v.end(),[](inta,intb){returnab;});4. 智能指针用于自动管理堆内存避免泄漏/重复释放。unique_ptr独占所有权不能拷贝只能移动效率接近裸指针。unique_ptrintp(newint(10));autop2std::move(p);shared_ptr引用计数共享线程安全的计数对象访问非线程安全。weak_ptr弱引用不增加引用计数解决 shared_ptr 循环引用。优先使用工厂函数make_uniqueT(...)// C14make_sharedT(...)5. 其他常用现代特性nullptr类型安全空指针替代NULL。列表初始化统一语法禁止窄化。noexcept声明函数不抛异常利于优化移动操作建议加。constexpr编译期计算性能更好。结构化绑定C17pairint,stringf();auto[id,name]f();七、STL 标准模板库1. 容器分类序列容器vector、list、deque、array、string关联容器set、map、multiset、multimap红黑树有序无序关联容器unordered_set、unordered_map哈希表平均 O(1)适配器stack、queue、priority_queue2. 常用容器选型需要随机访问、尾部增删快→vector需要任意位置频繁插入/删除→list需要头尾快速增删→deque需要key-value 有序查找→map需要最高查询性能、无序→unordered_map3. 迭代器行为类似指针提供统一遍历接口。区间[begin(), end())左闭右开。类型从弱到强输入 → 输出 → 前向 → 双向 → 随机访问cbegin()/cend()常量迭代器不能修改元素。4. 常用算法遍历for_each查找find、find_if、count、binary_search排序sort、stable_sort修改copy、replace、fill、reverse删除惯用手法erase-removev.erase(remove(v.begin(),v.end(),val),v.end());八、异常处理关键字try、throw、catch匹配规则从上到下类型优先匹配。捕获所有异常catch (...)标准异常继承自std::exception提供what()信息。常见标准异常bad_allocnew分配失败out_of_range越界invalid_argument无效参数RAII利用对象生命周期自动管理资源是异常安全的核心方案。智能指针lock_guard/unique_lock九、友元、运算符重载1. 友元友元函数/友元类可以访问类的private/protected成员。友元关系单向、不传递、不继承。典型场景重载/、工具类访问内部数据。classA{friendvoidfunc(Aa);friendclassB;};2. 运算符重载成员函数形式返回值 operator op(参数)非成员友元适合对称运算符、。不能重载的运算符::、.*、.、?:、sizeof、typeid自增自减区分前置T operator()后置T operator(int)流运算符/必须重载为非成员函数。十、常用工程惯用法RAII资源获取即初始化自动释放安全简洁。PImpl接口与实现分离降低编译依赖加速编译。移动优先能用移动就不用拷贝提升性能。尽量用 const提高可读性、安全性、优化空间。少用全局变量、宏易冲突、难调试。头文件保护#pragma once或#ifndef ... #define ... #endif。