模板与STL:模板基础
核心要点速览 意义:将类型作为参数,实现通用逻辑,编译期生成具体类型代码 分类:函数模板(可隐式实例化)、类模板(需显式实例化) 模板参数:类型参数(typename T)、非类型参数(编译期常量) 特化:全特化(所有参数指定类型)、偏特化(仅类模板支持,部分参数指定类型) 区别:模板有类型检查,宏无;模板支持特化 / 重载,宏不支持 一、模板的意义通过 “类型参数化” 让通用逻辑适配多种类型,既避免为不同类型重复编写相似代码(提升复用),又能在编译期进行类型检查(保证安全),且编译器会生成具体类型的代码(无运行时开销)。这也是 STL 容器(如 vector)和算法(如 sort)的实现基础。 二、函数模板定义生成具体函数的 “模板”,编译器根据实参类型自动实例化对应版本。 规则 语法:template<模板参数列表> 返回类型 函数名(参数列表) { ... } 实例化: 隐式实例化:编译器根据实参推导类型(如max(1,2)推导T=int)。 显式实例化:手动指定类型(如max<int>(1.5,2.5)强制T=int)。 重载:...
模板与STL:STL
核心要点速览 组件:容器(存储)、算法(操作)、迭代器(桥梁)、仿函数(自定义逻辑)、适配器(接口转换)、分配器(内存管理) 容器分类:序列式(vector/list/deque)、关联式(有序红黑树 / 无序哈希表)、适配器(stack/queue/priority_queue) 关键:底层实现、迭代器失效、容器选型、算法适用条件、内存与效率权衡 一、STL 组件 容器:类模板,封装数据结构(如 vector/map),存储数据的载体。 算法:函数模板,提供通用操作(sort/find),通过迭代器操作容器。 迭代器:类似指针的对象,提供元素访问接口,是容器与算法的桥梁。 仿函数:重载operator()的类 / 结构体(函数对象),传递自定义逻辑(比较 / 筛选)。 适配器:转换已有组件接口(含容器适配器、迭代器适配器如 reverse_iterator、函数适配器如 bind),如 stack 基于 deque 适配。 分配器:默认std::allocator,核心接口含alloc...
现代C++特性:右值引用和移动语义
核心要点速览 左值 vs 右值:左值有持久地址(可 & 取址),右值是临时对象 / 字面量(不可 & 取址) 右值引用(T&&):绑定右值,延长其生命周期,支持修改绑定对象 移动语义:通过移动构造 / 赋值转移资源(而非拷贝),提升性能(避免深拷贝) std::move:将左值转为右值引用(仅转换,不移动资源),原对象不应再使用 完美转发:std::forward 保持参数左值 / 右值属性,用于模板传递参数 一、左值与右值:值的分类1. 左值 定义:可放在赋值左侧,有持久内存地址,生命周期较长(如变量、函数返回的左值引用)。 特征:可被&取址(&a合法),可被赋值(a = 5合法)。 示例:int x = 10;(x 是左值)、int& func()(返回左值引用,是左值)。 2. 右值 定义:只能放在赋值右侧,无持久内存地址(或地址无意义),生命周期短暂。 分类: 纯右值:字面量(5、"hello")、表达式结果(x + y)、临时对象(func()返回非引用时)。...
现代C++特性:类型推导
核心要点速览 auto:基础推导忽略顶层 const / 引用,C++14 拓展至函数返回值与 lambda 参数,有明确使用限制。 decltype:精确保留类型(含 const / 引用),支持表达式推导,双层括号是推导左值引用的关键。 模板类型推导:分按值 / 按引用 / 万能引用三类场景,需特殊处理数组与函数名,核心是 “实参到形参的类型映射”。 进阶场景:decltype(auto) 结合两者优势,auto&& 适配多值类别,万能引用需搭配 std::forward 实现完美转发。 区别:auto 侧重 “简化声明”,decltype 侧重 “精确获取”,模板推导侧重 “参数适配”。 一、auto:自动推导变量类型用途是简化长类型声明,C++14 拓展了适用场景,推导逻辑聚焦 “忽略顶层修饰,保留底层约束”。 1. 推导规则 必须初始化:编译器依赖初始化表达式推导,未初始化编译报错(如auto x;报错)。 顶层 const / 引用忽略:变量本身的 const 和引用被舍弃,底层 const(指向常...
并发编程:线程同步
核心要点速览 数据竞争:多线程并发读写共享资源(至少一个写操作)的未定义行为 互斥锁:std::mutex(基础)、lock_guard(RAII 推荐)、unique_lock(灵活,配条件变量) 条件变量:wait()(阻塞 + 释锁)、notify_one()/notify_all(),需配互斥锁 + 谓词(解虚假唤醒) 原子操作:std::atomic(硬件级原子性,无锁),核心内存序(relaxed/acquire/release/seq_cst) 读写锁:std::shared_mutex(读共享、写独占),优化读多写少场景 常见问题:死锁(固定加锁顺序避免)、虚假唤醒(谓词检查解决)、活锁 / 饥饿(延迟 / 公平锁缓解) 一、线程同步的目标 保证数据一致性:避免多线程读写共享资源导致的结果不可预测。 控制执行顺序:确保线程按业务逻辑要求的顺序执行(如生产者先生产,消费者后消费)。 二、核心同步机制1. 互斥锁:独占式临界区访问 核心原理:通过 “加锁 - 操作 - 解锁”,保证同一时间仅一个线程进...
现代C++特性:结构化绑定
核心要点速览 适用类型:public 成员的结构体 / 类、pair/tuple、固定大小数组 /std::array、自定义适配类型 优势:语法简洁、支持 const / 引用绑定、无需提前声明变量 补充:std::tie对比、生命周期问题、非适用场景、底层依赖 一、语法格式:auto [变量1, 变量2, ...] = 复合类型;支持修饰符:const auto&(只读无拷贝)、auto&(修改原对象)、auto&&(C++20 右值绑定) 示例123456789101112// 1. 结构体/类(public成员)struct Point { int x; int y; };Point p = {1, 2};auto [a, b] = p; // 值拷贝绑定// 2. pair/tuplestd::pair<int, std::string> user = {101, "Alice"};auto [id, n...
并发编程:线程
核心要点速览 线程 vs 进程:进程是资源分配单位(独立内存),线程是调度单位(共享进程内存),线程通信成本更低 线程创建:std::thread支持函数、Lambda、函数对象三种方式 线程管理:join()等待回收、detach()分离(慎用)、joinable()检查状态 线程标识:std::this_thread::get_id()获取 ID,std::thread::id判断唯一性 线程状态:就绪、运行、阻塞、终止 常用接口: std::this_thread 命名空间提供 sleep_for、sleep_until、yield 等工具函数。 一、线程的概念1. 进程与线程的区别 特性 进程 (Process) 线程 (Thread) 定义 程序的一次执行实例,资源分配的最小单位。 进程内的执行单元,调度的最小单位。 资源 独立的代码、数据、堆栈空间。 共享进程的代码、全局数据,独立的栈和寄存器。 隔离 地址空间独立 (高隔离性)。 共享进程地址空间 (低隔离性)。 通信 进程间通信 (IPC),开销大。 直接共享数据,开销小。 开销 创建...
异常处理:异常传播与栈展开
核心要点速览 异常传播:无匹配catch时,异常逐层向上传递至调用者,直至捕获或触发std::terminate() 栈展开:传播过程中自动逆序销毁局部对象(按构造逆序),保障资源回收 规则:析构函数禁止抛异常(避免双重异常),未完全构造对象不执行析构 异常安全:依赖栈展开原子性 + RAII 机制,避免资源泄漏 补充:异常匹配优先精确 / 继承兼容,捕获const引用可避免异常切片 一、异常传播:从抛出点到捕获点的传递逻辑概念函数抛出异常且自身无匹配try-catch时,异常会沿函数调用栈逐层向上传播,依次遍历调用者上下文,直到被某个catch块捕获;若全程无捕获,程序调用std::terminate()终止(默认执行std::abort())。 传播流程 函数调用链:A→B→C,C 中抛出异常; C 无catch匹配,异常传播至 B; B 无catch匹配,继续传播至 A; A 的try块监控到异常,匹配catch执行处理; 若 A 仍无匹配,异常传播至main函数,最终未捕获则程序终止。 细节 异常传播时,被跳过函数中 “已执行但未进入try块” 的代码不再...
异常处理:异常基础与语法
核心要点速览 异常处理三关键字:throw(抛出异常)、try(监控异常代码)、catch(捕获处理异常),核心是分离错误检测与处理 基本流程:try监控→throw抛异常→catch匹配处理;无匹配则异常传播,最终未捕获则程序终止 匹配规则:catch按声明顺序匹配,子类异常需在父类前捕获,catch(...)(万能捕获)必须放最后 异常类型:推荐类类型(标准库异常或自定义类),可携带详细信息;避免基本类型(语义模糊) 一、三个关键字一、throw(抛出异常) 作用:检测到不可处理的错误(如参数非法)时,主动抛出异常对象,中断当前执行,通知上层处理。 语法:throw 表达式;(表达式结果为异常对象)。 细节: 异常类型选择: 不推荐基本类型(如throw 1,语义模糊,无法区分错误类型); 推荐类类型(如标准库std::invalid_argument),可携带详细信息(如"文件路径不能为空")。 执行逻辑:throw后,当前函数中后续代码立即终止,进入异常传播阶段(寻找匹配catch)。 二、try(监控异常) 作用:包裹可能抛出异常的代码...
异常处理:标准库异常与自定义异常
核心要点速览 标准库异常:以std::exception为基类,分逻辑错误(编译可避免)和运行时错误(运行不可预知)两大类,核心接口what()返回错误描述 自定义异常:推荐继承std::exception,重写what()(必须加noexcept),语义需贴合业务场景 核心原则:优先复用标准库异常,自定义异常兼顾兼容性与信息完整性,杜绝基本类型异常,避免滥用 一、标准库异常体系(<stdexcept>)结构标准库提供了一套统一的异常类继承体系,所有标准异常均派生自std::exception抽象基类。这种设计保证了异常处理的兼容性 —— 无论捕获具体异常还是统一捕获基类引用,都能有效处理,是面试中 “规范异常使用” 的核心考点。 基类:std::exception 接口:virtual const char* what() const noexcept; 纯虚函数,返回 C 风格错误描述字符串,子类必须重写该方法才能实例化。 特性:无参构造、拷贝构造、拷贝赋值均被标记为noexcept,确保异常对象自身的构造和拷贝过程不会抛出新异常(避免双重异常)。 异常分类...

