考试题总结
看清是否为虚函数!!!!!!
简述Lambda表达式的作用,并比较它与重载了函数调用操作符的函数对象的差别
Lambda 表达式的作用
- 定义匿名函数: 允许在需要的地方(如调用 STL 算法时)就地定义函数,无需单独命名。
- 实现闭包(Closure): 能够方便地捕获当前作用域内的局部变量(通过
[=]或[&])。 - 简化代码: 避免编写繁琐的小型函数或类,提高代码可读性和编写效率。
2. 与函数对象(Functor)的差别
- 本质关系: Lambda 表达式是函数对象的语法糖。在编译阶段,编译器会将 Lambda 转化为一个匿名的函数对象类。
- 语法形式: Lambda 更加简洁、内联,无需显式定义类名和
operator();函数对象需要显式定义类、成员变量及重载operator()。 - 状态管理: Lambda 通过捕获列表自动处理外部变量;函数对象必须通过成员变量和构造函数手动管理状态。
- 复用性: Lambda 适合一次性使用的局部逻辑;显式定义的函数对象适合多次复用或复杂的逻辑封装。
一句话总结(加分项): Lambda 表达式在底层就是一个重载了函数调用操作符的匿名类对象,它用更简洁的语法实现了函数对象的功能。
RAII
RAII 全称是 Resource Acquisition Is Initialization(资源获取即初始化)。RAII 利用了 C++ 栈对象在离开作用域(包括异常发生)时自动调用析构函数的机制,确保资源在任何情况下都能被释放,从而避免内存泄漏并保证异常安全性。
在保证异常安全性方面的作用
这是 RAII 最重要的价值,关键词是 栈展开 (Stack Unwinding)。
- 没有 RAII 时: 如果函数中间抛出异常,位于异常点之后的释放资源代码(如
delete或unlock)将被跳过,导致内存泄漏或死锁。 - 使用 RAII 时: C++ 保证在异常抛出并退出当前作用域时,会执行栈展开。栈展开过程中,所有已构造的局部对象的析构函数会被依次调用。
- 结论: 无论函数是正常返回还是因异常退出,RAII 都能确保析构函数被执行,从而保证资源一定会被释放,实现了强异常安全或基本异常安全。
Simula67
1980形成 C with class:Bjarne Stroustrup c++之父
1983正式命名C++:Rick Mascitti
结构化编程:Dijkstra
1994制定ANSI C++标准草案
Simula 67 引入了 Class (类) 的概念,支持数据抽象和程序组织。虽然 Simula 在组织大型程序方面表现优异,但它的运行效率太低(Execution speed),无法满足系统级编程的需求。
template 不要忘了typename
C++理念
C++ 旨在提供零开销抽象 (Zero-overhead abstraction)。它既保留了 C 语言的高效性和底层控制能力(系统级编程),又引入了面向对象编程(OOP)和泛型编程的特性,以提高代码的复用性和可维护性 。
📊 核心考点统计与趋势
首先,有一个非常有意思的现象:“历史与哲学” 和 “智能指针/RAII” 是绝对的高频考点,甚至可以说是必考题。
1. 🔁 重复考了多次的“必杀技” (High Frequency)
这部分内容如果不复习,丢分会很冤,因为它们几乎每年都换着花样出现:
- C++ 发展史与设计哲学
- Simula 67 的贡献:这简直是送分题的重灾区。2019 和 2022 都明确考到了。
- C++ 设计理念:2019 和 2022 都问了类似“设计思路”或“设计理念”的问题。
- C vs C++:2021 考了异同 。
- 智能指针 (Smart Pointer) & RAII
- 手写智能指针:这是一个极高频的编程题。2019 和 2022 都要求手写一个智能指针类。
- RAII 概念:2024 简答题直接问了什么是 RAII 及其作用 。
- 异常处理 (Exception Handling)
- 多态与切片:2019 、2022 和 2024 的代码阅读题都考了
try-catch。重点在于:catch的是基类还是子类?如果是传值(而不是引用),会发生对象切片(Slicing),导致多态失效。
- 多态与切片:2019 、2022 和 2024 的代码阅读题都考了
- 构造与析构的顺序
- 继承链中的顺序:2019 、2024 都在代码阅读中考察了构造(父->子)和析构(子->父)的顺序。
- 虚函数在构造/析构中:2019 专门考了在构造函数里调虚函数会发生什么(此时多态未生效,调的是当前类的函数)。
🧬 面向对象 (OOP) 相关考点
这部分是 C++ 的灵魂,考察非常细致,特别是涉及“多态”的底层机制。
- 虚函数与多态 (Polymorphism)
- 实现机制:2024 简答题问了“虚函数如何实现多态” 。
- 覆盖 (Override):代码阅读题常考子类是否正确覆盖了父类虚函数 。
- 虚析构函数:2024 代码题考察了如果父类析构不是
virtual,删除基类指针时子类析构不会被调用的经典内存泄漏问题 。 - 继承 (Inheritance)
- 菱形继承/虚继承:2022 和 2024 都问到了虚继承(Virtual Inheritance)是为了解决什么问题(菱形继承/数据冗余)。
- 对象切片 (Object Slicing):2024 简答题专门问了什么是对象切片 ,2021 的编程题也暗示了这个问题 。
- 运算符重载 (Operator Overloading)
- 这也是编程题的热门。
- 流操作符 (
<<):2021 和 2024 都要求重载。 - 数学运算 (
\*):2024 要求实现矩阵/长方体的乘法 。 - 下标 (
[]):2022 考了const和非const两个版本 。 - 解引用 (
\*,->):在智能指针题目中必考 。
- 流操作符 (
🔧 C++ 语法基础 (Syntax & Basics)
这部分考察你对 C++ 内存和特性的理解,能不能写出“Modern C++”的代码。
- 内存管理
- 堆 vs 栈 vs 静态区:2024 和 2019 都涉及了。特别是
static变量的生命周期。
- 堆 vs 栈 vs 静态区:2024 和 2019 都涉及了。特别是
- 指针与引用
- 指针 vs 引用:2022 简答题 。
- 数组 vs 指针:2024 简答题 。
- 移动语义 (Move Semantics) (重点!这是 C++11 后的核心)
- 左值引用 vs 右值引用:2022 简答题 和 2024 代码题 都考了
int &&和std::move。 - 拷贝构造 vs 移动构造:2024 简答题 。
- 宏 vs 模板/内联
- Define vs Template/Inline:2019 和 2024 都考了宏定义的劣势(无类型检查、副作用等)。
- 模板 (Templates)
- 函数模板:2022 编程题要求写一个通用的
sum函数 。 - 类模板:2021 编程题要求写基于模板的栈 。
- 函数模板:2022 编程题要求写一个通用的
💡 备考建议 (Friend-to-Friend)
看来这门课的老师非常看重底层机制(比如虚表、内存布局)和C++11 新特性(智能指针、移动语义)。
- 背一下历史:Simula 67 那个点,一定要背,属于送分题。
- 死磕智能指针:一定要能够手写一个简单的
SmartPtr类,包含构造、析构(delete指针)、拷贝构造(深拷贝或转移所有权)、重载*和->。 - 搞懂“对象切片”:弄清楚在
catch异常或者函数传参时,为什么传值会导致多态丢失。 - 移动语义:复习一下
std::move到底干了什么(只是强制类型转换),以及什么时候会触发移动构造函数。