- docs/teaching/OUTLINE.md、slides/day1-5.html、index.html:替换此前自定义的 4 天方案,严格对齐 docs/TRAINING_PLAN_2026.md「C++方向」Day1-5 课堂内容 (Day6-10 为纯项目实作,不在教案范围) - docs/teaching/examples/:官方方案书要求但仓库 p03/(wiki 抓取内容) 未覆盖的 QSS/Model-View/JSON/QThread/QPropertyAnimation/QStateMachine 六个技术点, 各补一个最小可运行示例 + README 教学文档,均已离屏验证跑通;手工维护, 不属于 gen_part3.py 生成产物 - 根 CMakeLists.txt:接入 docs/teaching/examples 构建(BUILD_QT_PART 分支内), 不改动生成器管理的 p01/p03 CMakeLists - 任务卡改为目标/验收标准/基础知识参考三段式模板,custom.css 配套新增样式 - docs/teaching/PRETEST.md:10 题 10 分钟 C++ 摸底测验,验证教案假定的受众 基础是否成立,并与 OUTLINE.md §0 的分层预案挂钩
6.2 KiB
C++ 基础摸底小测验(10 题,预计 10 分钟)
用途:验证
docs/teaching/OUTLINE.md§0 里"学员已掌握 C++ 基础语法与 OOP 概念"这条假设是否成立。建议在 Day1 模块 B 开始前(C++ 回顾环节之前) 发给学员,闭卷、不查资料,10 分钟内独立完成。题型:选择题 + 代码阅读(判断输出/找 bug)+ 1 道简答,覆盖 Day1 回顾要点 涉及的引用、重载、构造析构顺序、虚函数多态、运算符重载、模板、STL、 const、深浅拷贝九个知识点。
第 1 题(选择,30 秒)
下列关于"引用"和"指针"的说法,错误的是?
A. 引用必须在定义时初始化
B. 引用可以为 nullptr
C. 引用一旦绑定就不能再指向其他对象
D. 函数参数用引用可以避免拷贝开销
第 2 题(代码阅读,1 分钟)
void f(int x) { std::cout << "int " << x; }
void f(double x) { std::cout << "double " << x; }
int main() { f(3.0f); }
这段代码输出什么?
第 3 题(选择,30 秒)
关于虚函数,下列说法正确的是?
A. 基类析构函数不加 virtual,通过基类指针 delete 派生类对象一定不会有问题
B. 构造函数可以是虚函数
C. 纯虚函数所在的类不能被直接实例化
D. 派生类必须重写基类的每一个虚函数
第 4 题(代码阅读,1 分钟)
class A { public: A(){ std::cout<<"A"; } ~A(){ std::cout<<"~A"; } };
class B : public A { public: B(){ std::cout<<"B"; } ~B(){ std::cout<<"~B"; } };
int main(){ B b; }
请写出输出的完整顺序。
第 5 题(找 bug,1.5 分钟)
class Buffer {
char* data;
public:
Buffer(int n) { data = new char[n]; }
~Buffer() { delete[] data; }
};
void use() {
Buffer a(10);
Buffer b = a; // 用 a 拷贝构造 b
}
use() 函数运行到结束时会发生什么问题?请说明原因。
第 6 题(选择,30 秒)
关于函数模板,下列说法正确的是?
A. 模板函数一旦定义,编译器就会为所有可能的类型生成代码 B. 编译器会根据调用时的实参类型自动推导模板参数,并生成对应的实例 C. 模板函数不能被重载 D. 调用模板函数时必须显式指定所有模板参数
第 7 题(代码阅读,1 分钟)
std::vector<int> v = {3, 1, 4, 1, 5};
for (int x : v) {
if (x % 2 == 0) std::cout << x;
}
这段代码输出什么?
第 8 题(选择,30 秒)
下列哪个函数声明表示"这个成员函数不会修改对象的成员变量"?
A. void print()
B. void print() const
C. const void print()
D. void const print()
第 9 题(代码阅读,1 分钟)
class Point {
public:
int x, y;
Point operator+(const Point& other) const {
return Point{x + other.x, y + other.y};
}
};
Point p1{1, 2}, p2{3, 4};
Point p3 = p1 + p2;
std::cout << p3.x << "," << p3.y;
这段代码输出什么?
第 10 题(简答,1.5 分钟)
用一两句话说明"深拷贝"和"浅拷贝"的区别,以及为什么一个类里如果有指针成员、 又没有自己实现拷贝构造函数,可能会引发问题。
答案与评分(教师用,建议测验时不发给学员)
| 题号 | 答案 | 对应知识点 · 出处 |
|---|---|---|
| 1 | B(引用不能为空,这是它和指针的关键区别之一) | 引用的本质 · p01/ch03/reference_essence.cpp |
| 2 | double 3(float 到 double 是浮点提升,比 float 到 int 的转换更优先匹配 f(double)) |
函数重载决议 · p01/ch03/function_overload_mechanism.cpp |
| 3 | C(A 错——没有 virtual 析构会导致派生类部分不被析构;B 错——构造函数不能是虚函数;D 错——不重写就继承基类实现,纯虚函数才必须重写) | 虚函数与抽象类 · p01/ch04/s08 |
| 4 | A B ~B ~A(先构造基类再构造派生类;析构顺序相反) |
继承中构造/析构顺序 · p01/ch04/s07/inheritance_ctor_dtor_order.cpp |
| 5 | 浅拷贝:b 的 data 和 a 的 data 指向同一块内存;函数结束时 ~Buffer() 被调用两次,对同一块内存 delete[] 两次(double free),行为未定义/可能崩溃 |
深拷贝 vs 浅拷贝 · p01/ch04/s03/deep_vs_shallow_copy.cpp |
| 6 | B(模板是"按需实例化",不是提前生成所有版本) | 函数模板 · p01/ch05/function_template.cpp |
| 7 | 4(3,1,4,1,5 里只有 4 是偶数) |
STL 容器与范围 for · p01/ch09/s03/vector_iterator.cpp |
| 8 | B(const 放在参数列表后面,修饰的是"this 指向的对象不可修改") |
const 成员函数 · p01/ch04/s04/const_member_function.cpp |
| 9 | 4,6(1+3=4,2+4=6) |
运算符重载 · p01/ch04/s06/overload_assignment.cpp |
| 10 | 浅拷贝只复制指针本身(地址),深拷贝复制指针指向的内容;没有自定义拷贝构造函数时,编译器生成的默认拷贝构造函数是浅拷贝,两个对象的指针成员会指向同一块内存,析构时重复释放(double free)或修改一个对象的数据影响另一个对象 | 深拷贝 vs 浅拷贝 · p01/ch04/s03/deep_vs_shallow_copy.cpp |
评分建议
- 8–10 题正确:具备
OUTLINE.md§0 假设的基础,按 Day1 模块 B 原定的 "巡礼式回顾"节奏推进即可。 - 5–7 题正确:部分薄弱点——对照上表找出学员集中出错的知识点(比如普遍 在第 4/5 题失分,说明构造析构顺序和深浅拷贝没吃透),讲课时在对应知识点 多花 5–10 分钟,其余部分维持原节奏。
- 0–4 题正确:明显达不到"已掌握 C++ 基础语法与 OOP 概念"的假设——按
OUTLINE.md§0 里的预案,Day1 模块 B 的讲授部分退回到语法讲解,练习任务 保持不变但预期完成度应下调,不需要重排整个教案结构。
使用方式
- 建议纸质或线上表单均可,闭卷、不查资料、不讨论,10 分钟收卷;
- 只用于摸底分层,不计入
docs/TRAINING_PLAN_2026.md的正式考核成绩; - 大规模学员时可以只统计"每题正确率"而不用逐份细看,正确率低于 50% 的题 对应知识点在 Day1 模块 B 里适当加时。