幻灯片按 4 天版重排:Day1 全 C++、Day3 启用 ch05/ch06、Day5 综合案例

- Day1:开训 + 全天 C++(PRETEST 摸底环节内联;★所有权/★编译 vs 链接错误新卡)
- Day2:Qt 入门 + 信号槽 → 计算器(★栈控件双重释放/★lambda 第五参数/
  ★重复 connect/★QString 中文编码,均链到坑点复现示例)
- Day3:QMainWindow/QDialog(p03/ch05、ch06 首次排课,☆两张新卡)+ 布局/控件/QSS
- Day4:事件/绘图/QTableWidget + 文件系统/JSON(★工作目录/★文件编码)
- Day5:综合案例全天(student_manager 走查 + QThread 提升 + 流程规范)
- index.html 同步 4+1 结构;相对链接脚本校验 0 失效
This commit is contained in:
张宗平
2026-07-05 12:49:44 +08:00
parent 1053ebf41c
commit 0f81edcc74
6 changed files with 880 additions and 1132 deletions
+228 -278
View File
@@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>Day 1 · 开训 + C++ 回顾/工具链</title>
<title>Day 1 · 开训 + C++ 回顾与提升(全天)</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="reveal/reveal.css">
<link rel="stylesheet" href="reveal/theme.css">
@@ -15,277 +15,55 @@
<section>
<h1>Day 1</h1>
<h3>开训 + C++ 回顾/工具链</h3>
<p class="module-badge">C++/Qt 方向实训 · 第 1 / 5 天 · 对齐官方方案书 Day1</p>
<h3>开训 + C++ 回顾与提升(全天 C++</h3>
<p class="module-badge">C++/Qt 方向实训 · 第 1 / 4 个讲授日 · 对齐 2026-07 新版 10 天安排</p>
<ul>
<li>模块 A(3 课时):团队建设 / 敏捷 Scrum / C++ 在企业中的应用(讨论型,无编码)</li>
<li>模块 B(3 课时):C++ 环境搭建 / 高级程序回顾 / CMake / Vcpkg(压缩讲解)</li>
<li>上午(08:3011:00 讲 / 11:0012:00 练):开训 · C++ 技术版图 · 环境与 CMake · OOP 回顾</li>
<li>下午(13:3016:00 讲 / 16:0017:00 作业):继承与多态 · 内存管理 · STL 常用容器</li>
</ul>
<p><small>本教案假定学员已掌握 C++ 基础语法与 OOP 概念——方案书对今天下午的
官方定位是"回顾和提升",不是零基础教学。今天开始的 5 天覆盖方案书 C++方向
Day1–5 全部课堂内容,Day6–10 是纯项目实作。</small></p>
<p><small>本教案假定学员已掌握 C++ 基础语法与 OOP 概念——今天定位是"回顾和提升",
不是零基础教学。Day1–4 讲授,Day5 综合案例,Day6–10 项目开发与答辩。
大纲:<a class="filelink" target="_blank" href="../OUTLINE_4DAY.md">docs/teaching/OUTLINE_4DAY.md</a></small></p>
<div class="verify-box" style="font-size:0.5em;">
<h4>模块 B 开始前:10 分钟摸底测验</h4>
<p>这条假设不是拍脑袋定的——建议模块 B 讲授前先用
<a class="filelink" target="_blank" href="../PRETEST.md">docs/teaching/PRETEST.md</a>
(10 题、10 分钟)实测一次,按结果决定原节奏推进还是回退到语法讲解。</p>
<h4>OOP 回顾开讲前:10 分钟摸底测验</h4>
<p>受众假设要实测——用 <a class="filelink" target="_blank" href="../PRETEST.md">docs/teaching/PRETEST.md</a>
(10 题、10 分钟、A/B 平行卷)测一次,按结果决定回顾环节推进速度(分层预案见该文件)。</p>
</div>
</section>
<!-- ===================== 模块 A:讲 ===================== -->
<!-- ===================== 上午:讲 ===================== -->
<section>
<section>
<p class="module-badge">模块 A · 讲授 35min</p>
<h2>团队建设 / 敏捷 Scrum / C++ 企业应用 <span class="tag tag-lecture"></span></h2>
<p class="module-badge">上午 · 讲授 08:3011:00(讲 2530min + 随堂练 1015min 循环)</p>
<h2>开训 / C++ 技术版图 / 环境与 CMake / OOP 回顾 <span class="tag tag-lecture"></span></h2>
<ul>
<li>团队建设与文化、实训安排考评要求</li>
<li>项目开发过程管理全景(JIRA / Git / OASIS / Wiki</li>
<li>敏捷 Scrum 项目开发管理</li>
<li>C++ 在企业中的应用</li>
<li>开训典礼:团队文化 · 实训安排 · 考评要求(组织方主持)</li>
<li>C++ 常用技术和框架(讲座</li>
<li>开发环境搭建 + Makefile/CMake 项目构建</li>
<li>PRETEST 摸底(10min)→ 面向对象基础回顾(类/对象/封装)</li>
</ul>
</section>
<section>
<h3>实习实训服务流程 <span class="tag tag-lecture"></span></h3>
<img src="../../images/training_service_flow.png" style="max-height:520px;">
<p><small>出处:<a class="filelink" target="_blank"
href="../../TRAINING_PLAN_2026.md">docs/TRAINING_PLAN_2026.md</a> 「六、实习实训服务流程」</small></p>
</section>
<section>
<h3>服务流程:核心概念 <span class="tag tag-lecture"></span></h3>
<h3>C++ 常用技术和框架(讲座) <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<h4>核心概念——C++ 的四大应用版图</h4>
<ul>
<li>需求分析→需求评审→项目研发/代码实现→阶段评审→项目测试/交付——每个环节都有明确的
"评审"节点把关,不是写完代码就结束,这就是接下来 Day6–10 项目实作要走的完整流程。</li>
<li><b>桌面客户端</b>:Qt(本次实训主线)、跨平台 GUI;</li>
<li><b>服务端/基础设施</b>:高性能网络服务、数据库引擎、游戏服务器;</li>
<li><b>嵌入式/车载</b>:资源受限环境里 C++ 仍是第一梯队选择;</li>
<li><b>游戏/图形</b>UE 引擎、渲染管线。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见误区</h4>
<ul>
<li>把"需求分析"当成走过场:跳过评审直接开始编码,后期返工成本远高于前期多花时间对齐需求。</li>
</ul>
</div>
</section>
<section>
<h3>质量保证:四平台一标准 <span class="tag tag-lecture"></span></h3>
<img src="../../images/quality_four_platforms.png" style="max-height:520px;">
<p><small>出处:<a class="filelink" target="_blank"
href="../../TRAINING_PLAN_2026.md">docs/TRAINING_PLAN_2026.md</a> 「七、质量保证」</small></p>
</section>
<section>
<h3>四平台一标准:核心概念 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<h4>而且它还在进化</h4>
<ul>
<li>JIRA(任务跟踪)+ Git(版本管理)+ Wiki 知识库 + OASIS 绿洲实训管理平台,四个工具
分别对应"谁在做什么/代码怎么变化/知识怎么沉淀/进度怎么被看到"四个不同维度,缺一个都会
让协作出现盲区。</li>
<li>C++11 起三年一版:11「几乎新语言」→ 17 实用大件 → 20 四大件(Concepts/Ranges/协程/模块)。
今天下午末尾有专门一页巡礼;深入自学:
<a class="filelink" target="_blank" href="../MODERN_CPP.md">MODERN_CPP.md</a> ·
<a class="filelink" target="_blank" href="../MODERN_CPP_20PLUS.md">MODERN_CPP_20PLUS.md</a></li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见误区</h4>
<ul>
<li>只用 Git 不用 Jira:代码有了版本历史,但"谁负责什么、进度到哪"没有可见记录,
团队协作时容易重复劳动或漏项。</li>
</ul>
</div>
</section>
</section>
<!-- ===================== 模块 A:讨论(无编码) ===================== -->
<section>
<section>
<p class="module-badge">模块 A · 讨论 95min(分组,非编码)</p>
<h2>动手:分组讨论 <span class="tag tag-discuss"></span></h2>
<p><small>今天上午没有编码练习——先把协作流程和项目方向定下来,Day6–10
的项目实作会真的用到今天讨论的结论。</small></p>
</section>
<section>
<div class="task-card discuss-card">
<h4>任务卡 1 · 协作分工 <span class="tag tag-discuss"></span></h4>
<dl class="task-spec">
<dt>目标</dt>
<dd>结合服务流程图,说清楚本组打算怎么分工使用 Jira(任务跟踪)+ Git(代码版本管理)</dd>
<dt>验收标准</dt>
<dd>每组提交一句话分工说明(谁负责建 Jira 看板 / 谁负责 Git 仓库初始化),能在图上指出对应环节</dd>
<dt>基础知识 · 参考</dt>
<dd>上一节"实习实训服务流程"图 ·
<a class="filelink" target="_blank" href="../../TRAINING_PLAN_2026.md">TRAINING_PLAN_2026.md 「七、质量保证 (一)(二)」</a></dd>
</dl>
</div>
</section>
<section>
<div class="task-card discuss-card">
<h4>任务卡 2 · 选定项目方向 <span class="tag tag-discuss"></span></h4>
<dl class="task-spec">
<dt>目标</dt>
<dd>选定实训期间打算做的项目方向(Linux C 方向,或 C++/Qt 方向的备选商业项目之一)</dd>
<dt>验收标准</dt>
<dd>每组报出项目名称 + 一句话说明选择理由</dd>
<dt>基础知识 · 参考</dt>
<dd><a class="filelink" target="_blank" href="../../TRAINING_PLAN_2026.md">TRAINING_PLAN_2026.md 「八、备选商业项目介绍」</a></dd>
</dl>
</div>
</section>
</section>
<!-- ===================== 模块 B:讲 ===================== -->
<section>
<section>
<p class="module-badge">模块 B · 讲授 35min(巡礼式,压缩讲解)</p>
<h2>C++ 回顾 / CMake / Vcpkg <span class="tag tag-lecture"></span></h2>
<p><small>只挑「学过但容易讲不透」的点,不逐章展开——方案书官方定位是
"回顾和提升",深度让位于 Day2–5 的 Qt 内容。</small></p>
</section>
<section>
<h3>namespace 作用域 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>"作用域"不是"文件顺序"——很多人误以为 namespace 只是给名字加前缀,实际上它定义的是
一段可以被跨文件延续、跨块合并的作用域,同一个命名空间可以在多个文件里反复打开、追加内容。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>在头文件里写 <code>using namespace std;</code>:会把整个命名空间污染带给所有
include 这个头文件的地方,容易引发命名冲突,规范做法是只在 .cpp 里用,或干脆不用、
全程写限定名。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch03/namespace_syntax.cpp">p01/ch03/namespace_syntax.cpp</a>
对照 <a class="filelink" target="_blank" href="../../ERRATA.md">docs/ERRATA.md</a></small></p>
</section>
<section>
<h3>函数重载决议 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>编译器靠"名字改写"name mangling)把重载函数变成不同的符号;二义性往往不是代码写
错了,而是重载集合里存在两个"一样好"的候选,编译器无法替你选。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>隐式类型转换会扩大重载候选集——比如 <code>int</code>/<code>double</code> 都能转
<code>float</code> 参数,传一个 <code>long</code> 进去可能触发意料之外的重载版本。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch03/function_overload_mechanism.cpp">p01/ch03/function_overload_mechanism.cpp</a></small></p>
</section>
<section>
<h3>引用的本质 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>把引用理解成"自动解引用的 const 指针"——这个实现视角能解释引用为什么必须初始化、
为什么不能重新绑定到另一个对象。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>返回局部变量的引用:函数结束局部变量已销毁,返回的引用变成悬空引用,后续访问是
未定义行为——和返回局部变量指针是同一类坑。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch03/reference_essence.cpp">p01/ch03/reference_essence.cpp</a></small></p>
</section>
<section>
<h3>虚析构与内存泄漏 <span class="tag tag-lecture"></span></h3>
<pre><code class="cpp" data-trim data-noescape>
Base* p = new Derived();
delete p; // 如果 ~Base() 不是 virtual~Derived() 不会被调用——经典泄漏
</code></pre>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>通过基类指针 <code>delete</code> 派生类对象时,只有基类析构函数是 <code>virtual</code>
才会走虚函数表找到派生类的析构函数——这是"多态"在析构这个场景下的具体体现。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>只要一个类可能被继承、且可能通过基类指针删除派生对象,就应该把析构函数声明为
<code>virtual</code>——即使当前基类本身没什么要清理的,这是个防御性约定。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch04/s08/virtual_dtor_purpose.cpp">p01/ch04/s08/virtual_dtor_purpose.cpp</a></small></p>
</section>
<section>
<h3>模板与 STL 速览 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>只点名,不展开:泛型编程(函数模板/类模板)让同一份代码适配不同类型,容器/迭代器
是 Day6–10 项目实作里会大量用到的基础设施——迭代器是"容器和算法之间的统一接口",这也是
STL 能让算法脱离具体容器类型复用的关键。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>容器扩容/删除元素后,之前保存的迭代器可能失效(如 <code>vector</code> 扩容),
继续用失效的迭代器是未定义行为——遍历中增删元素前要先弄清对应容器的迭代器失效规则。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch05/class_template_basics.cpp">p01/ch05/class_template_basics.cpp</a>
<a class="filelink" target="_blank" href="../../../p01/ch09/s03/vector_iterator.cpp">p01/ch09/s03/vector_iterator.cpp</a></small></p>
</section>
<section>
<h3>C++11/14/17/20+:一门仍在进化的语言 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念——每 3 年一次实打实的能力升级,不是小修小补</h4>
<ul>
<li><b>C++11</b>"现代 C++ 元年"):<code>auto</code> 类型推导、智能指针
<code>unique_ptr</code>/<code>shared_ptr</code>RAII 终结手动 <code>new</code>/<code>delete</code>)、
右值引用 <code>&amp;&amp;</code> + 移动语义(消除不必要的拷贝)、lambda 表达式、
语言级并发 <code>std::thread</code>/<code>mutex</code>/<code>atomic</code>
<code>nullptr</code><code>constexpr</code></li>
<li><b>C++14</b>:泛型 lambda(参数写 <code>auto</code>)、函数返回类型自动推导、
<code>std::make_unique</code> 补齐。</li>
<li><b>C++17</b>:结构化绑定 <code>auto [a,b] = pair</code><code>if</code>/<code>switch</code>
带初始化语句、<code>std::optional</code>/<code>variant</code>/<code>string_view</code>
标准库终于有跨平台的 <code>std::filesystem</code></li>
<li><b>C++20</b>(号称"自 C++11 以来最大的一次变革"):concepts 概念(模板约束,报错从
几百行天书变成一句话)、ranges 范围库(<code>view | filter | transform</code> 管道式组合)、
coroutines 协程(<code>co_await</code> 把异步代码写成同步的样子)、modules 模块(挑战头文件
体系)、<code>&lt;=&gt;</code> 三路比较一行换 6 个运算符。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>新标准 ≠ 现在能用:生产环境的编译器/CI 常年落后最新标准 1–2 个版本,用新特性前先确认
目标工具链 <code>-std=</code> 支持到哪。本仓库出于教学稳定性选 C++17 作为基线(顶层
<code>CMakeLists.txt</code>),可用 <code>tools/std_probe.py</code> 自己验证某特性最早从哪个
标准开始能编译(宿主 gcc 13.3 原生支持到 C++23)。</li>
</ul>
</div>
<div class="verify-box">
<h4>缺口说明</h4>
<p>本节为纯概念巡礼,无对应仓库示例——具体新特性的动手练习超出本次"C++回顾"压缩讲解范畴,
感兴趣可用 <code>tools/std_probe.py</code> + <code>tools/demo_versions/</code> 自行探索
(参见 <a class="filelink" target="_blank" href="../../VERSION_NOTES.md">docs/VERSION_NOTES.md</a>)。</p>
</div>
</section>
<section>
@@ -296,51 +74,72 @@ cmake --build build # 144 个目标全绿</code></pre>
<h4>核心概念</h4>
<ul>
<li>CMake 是"生成构建系统的工具"而不是构建系统本身:<code>cmake -S -B</code>
<code>CMakeLists.txt</code> 生成 Ninja/Makefile 工程,<code>cmake --build</code> 才是
真正编译。<code>option(BUILD_QT_PART)</code> 控制是否编译 Qt 部分,每个示例一个
<code>add_executable</code> 目标,这就是"一文件一目标"约定的由来。</li>
<code>CMakeLists.txt</code> 生成 Ninja/<b>Makefile</b> 工程(Makefile 是它的生成目标之一——
这就是两者的关系),<code>cmake --build</code> 才是真正编译。
<code>option(BUILD_QT_PART)</code> 控制是否编译 Qt 部分,每个示例一个
<code>add_executable</code> 目标。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>改了 <code>CMakeLists.txt</code> 却没重新 <code>cmake</code> 配置(只 <code>build</code>):
大多数改动 CMake 会自动侦测重新配置,但换生成器/清缓存等情况需要重新走
<code>-S -B</code> 一次。</li>
<li>改了 <code>CMakeLists.txt</code> 却没重新配置:大多数改动 CMake 会自动侦测,
但换生成器/清缓存需要重新走一次 <code>-S -B</code></li>
</ul>
</div>
<p><small>出处:仓库根 <a class="filelink" target="_blank" href="../../../CMakeLists.txt">CMakeLists.txt</a></small></p>
<p><small>出处:仓库根 <a class="filelink" target="_blank" href="../../../CMakeLists.txt">CMakeLists.txt</a>
· 包管理器一分钟:vcpkg 用 toolchain 文件让 <code>find_package</code> 自动找到三方库;
本仓库选"隔离 Qt 手动装",两种思路都要认识。</small></p>
</section>
<section>
<h3>Vcpkg 包管理器(概念,无演示) <span class="tag tag-lecture"></span></h3>
<h3>★ 编译错误 vs 链接错误:排查方向完全不同 <span class="tag tag-lecture"></span></h3>
<pre><code class="text" data-trim>main.cpp:12:5: error: 'foo' was not declared ← 编译期:带文件行号
main.o: undefined reference to `Widget::bar()' ← 链接期:没有行号</code></pre>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>C++ 生态的包管理器,解决"第三方库怎么装、怎么被 CMake 找到"的问题——一次
<code>vcpkg install</code>,配合 CMake 的 toolchain 文件,<code>find_package</code>
就能自动找到头文件和库</li>
<li><code>error:</code> 带行号 = 编译期问题(语法/类型/没声明)——回代码里查那一行;
<code>undefined reference</code> 无行号 = 链接期问题(有声明没定义/缺库/缺目标文件)——
查"定义在哪、链没链进来",回头检查语法是南辕北辙</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>不是所有第三方库都必须用包管理器装——本仓库用的是"隔离 Qt 手动装"
<code>tools/install_qt_host.sh</code>)而非 vcpkg,两种思路都要认识:包管理器省心但
引入额外工具链,手动隔离装则精确控制版本/路径,各有取舍。</li>
<li>中初级学员见到 <code>undefined reference</code> 的第一反应是检查拼写和语法——方向就错了。
明天 Qt 的"忘写 <code>Q_OBJECT</code>"报的正是链接错误,且报错完全不提宏,记住今天这页。</li>
</ul>
</div>
<div class="verify-box">
<h4>缺口说明</h4>
<p>本仓库暂无 vcpkg 可运行示例——安装真实 vcpkg 工具链超出最小示例范畴,此处仅作概念介绍。</p>
</section>
<section>
<h3>OOP 回顾:类 / 对象 / 封装 + namespace <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>封装 = 数据和操作绑定 + 访问控制(public/private 是给"人"划的边界,不是安全机制);
构造/析构对应对象生命周期的两端——这个心智模型下午的"所有权"还要用。</li>
<li>namespace 的"作用域"不是"文件顺序":可跨文件延续、跨块合并。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>头文件里 <code>using namespace std;</code> 会把命名空间污染带给所有 include 它的
地方——只在 .cpp 用,或全程写限定名。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank" href="../../../p01/ch04/">p01/ch04/</a>(类与对象各节)、
<a class="filelink" target="_blank" href="../../../p01/ch03/namespace_syntax.cpp">p01/ch03/namespace_syntax.cpp</a>
对照 <a class="filelink" target="_blank" href="../../ERRATA.md">docs/ERRATA.md</a></small></p>
</section>
</section>
<!-- ===================== 模块 B:练 ===================== -->
<!-- ===================== 上午:练 ===================== -->
<section>
<section>
<p class="module-badge">模块 B · 练习 95min</p>
<p class="module-badge">上午 · 课堂练习 11:00–12:00(工程师指导、答疑)</p>
<h2>动手:走一遍真实构建流程 <span class="tag tag-practice"></span></h2>
</section>
<section>
@@ -358,13 +157,165 @@ cmake --build build # 144 个目标全绿</code></pre>
</dl>
</div>
</section>
</section>
<!-- ===================== 下午:讲 ===================== -->
<section>
<section>
<p class="module-badge">下午 · 讲授 13:3016:00</p>
<h2>继承与多态 / 内存管理 / STL <span class="tag tag-lecture"></span></h2>
<ul>
<li>C++ 核心特性:继承与多态、虚函数(含虚析构)</li>
<li>内存管理:指针、引用与动态分配(含★所有权模型)</li>
<li>STL 常用容器简介</li>
<li>收尾:现代 C++ 巡礼(兴趣钩子)</li>
</ul>
</section>
<section>
<h3>函数重载决议 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>编译器靠"名字改写"name mangling)把重载函数变成不同符号;二义性往往不是代码写错,
而是重载集合里有两个"一样好"的候选,编译器无法替你选。重载(编译期,同类内) vs
重写(运行期,继承体系) 是两码事。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>隐式类型转换会扩大重载候选集——传一个 <code>long</code> 进去可能触发意料之外的重载版本。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch03/function_overload_mechanism.cpp">p01/ch03/function_overload_mechanism.cpp</a></small></p>
</section>
<section>
<h3>虚函数与虚析构 <span class="tag tag-lecture"></span></h3>
<pre><code class="cpp" data-trim data-noescape>
Base* p = new Derived();
delete p; // 如果 ~Base() 不是 virtual~Derived() 不会被调用——经典泄漏
</code></pre>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>通过基类指针 <code>delete</code> 派生类对象时,只有基类析构是 <code>virtual</code>
才会走虚函数表找到派生类析构——"多态"在析构场景下的具体体现。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>只要类可能被继承 + 可能经基类指针删除,析构就该 <code>virtual</code>——防御性约定。
(明天会看到 Qt 的 QObject 体系全线虚析构。)</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch04/s08/virtual_dtor_purpose.cpp">p01/ch04/s08/virtual_dtor_purpose.cpp</a></small></p>
</section>
<section>
<h3>引用的本质 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>把引用理解成"自动解引用的 const 指针"——这个实现视角能解释为什么必须初始化、
为什么不能重新绑定。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>返回局部变量的引用:函数结束局部变量已销毁,引用悬空,访问是未定义行为——
和返回局部变量指针同一类坑。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch03/reference_essence.cpp">p01/ch03/reference_essence.cpp</a></small></p>
</section>
<section>
<h3>★ 所有权:谁负责 delete <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>内存管理的核心问题不是"会不会 new",而是<b>"这块资源归谁管、由谁释放"</b>
现代答案是 RAII/智能指针:<code>unique_ptr</code> 独占所有权、<code>shared_ptr</code>
共享所有权(详见 <a class="filelink" target="_blank" href="../MODERN_CPP.md">MODERN_CPP.md</a> §2)。
一个对象只能有一个所有者。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>双重释放、忘记释放、释放后使用——三兄弟全部源于所有权不明。</li>
<li><b>明天的伏笔</b>Qt 用"父子树"回答同一个问题(parent 析构自动 delete 子对象)。
两套所有权体系<b>不能混用</b>——交给 Qt 树管的对象,不要再用智能指针/栈/手动 delete 管。</li>
</ul>
</div>
</section>
<section>
<h3>模板与 STL 常用容器 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>泛型编程让同一份代码适配不同类型;<code>vector</code>/<code>map</code>/<code>string</code>
是项目实作三件套;迭代器是"容器和算法之间的统一接口"——STL 算法能脱离具体容器复用的关键。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>容器扩容/删除元素后,旧迭代器可能失效(如 <code>vector</code> 扩容搬家),继续用是
未定义行为——遍历中增删元素前先弄清该容器的失效规则。</li>
</ul>
</div>
<p><small>出处:<a class="filelink" target="_blank"
href="../../../p01/ch05/class_template_basics.cpp">p01/ch05/class_template_basics.cpp</a>
<a class="filelink" target="_blank" href="../../../p01/ch09/s03/vector_iterator.cpp">p01/ch09/s03/vector_iterator.cpp</a></small></p>
</section>
<section>
<h3>钩子 · C++11/14/17/20+:一门仍在进化的语言 <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念——每 3 年一次实打实的能力升级</h4>
<ul>
<li><b>C++11</b>:auto · 智能指针 · 移动语义 · lambda · 语言级并发 —— "现代 C++ 元年"</li>
<li><b>C++14</b>:泛型 lambda · 返回类型推导 · <code>make_unique</code></li>
<li><b>C++17</b>:结构化绑定 · if-init · optional/variant/string_view · filesystem(本仓库基线);</li>
<li><b>C++20</b>Concepts · Ranges · 协程 · 模块 —— "自 C++11 以来最大变革"。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>新标准 ≠ 现在能用:生产工具链常年落后 1–2 版。用 <code>tools/std_probe.py</code>
自己验证某特性从哪个标准开始能编译(宿主 gcc 13.3 支持到 C++23)。</li>
</ul>
</div>
<p><small>自学入口:<a class="filelink" target="_blank" href="../MODERN_CPP.md">MODERN_CPP.md</a>11/14/17
示例全部可在本仓库基线下编译) ·
<a class="filelink" target="_blank" href="../MODERN_CPP_20PLUS.md">MODERN_CPP_20PLUS.md</a>20/23/26 前瞻,
含本机 GCC 实测矩阵)</small></p>
</section>
</section>
<!-- ===================== 下午:作业 ===================== -->
<section>
<section>
<p class="module-badge">下午 · 课堂作业 16:00–17:00(工程师答疑)</p>
<h2>作业 <span class="tag tag-practice"></span></h2>
</section>
<section>
<div class="task-card">
<h4>任务卡 2 · 修一个真实的坑 <span class="tag tag-practice"></span></h4>
<dl class="task-spec">
<dt>目标</dt>
<dd><a class="filelink" target="_blank" href="../../ERRATA.md">docs/ERRATA.md</a>
挑 2 条记录,理解"wiki 原文错在哪、现在的写法为什么"</dd>
挑 2 条与今天知识点相关的记录(虚析构/引用/重载类),理解"wiki 原文错在哪、为什么"</dd>
<dt>验收标准</dt>
<dd>能用一句话向同组同学解释清楚,不能只念代码</dd>
<dt>基础知识 · 参考</dt>
@@ -377,13 +328,12 @@ cmake --build build # 144 个目标全绿</code></pre>
<h4>任务卡 3(选做)· 版本探针 <span class="tag tag-practice"></span></h4>
<dl class="task-spec">
<dt>目标</dt>
<dd><code>tools/std_probe.py</code> 验证一个标准版本差异点(如三目运算符可否作左值)</dd>
<dd><code>tools/std_probe.py</code> 验证一个标准版本差异点</dd>
<dt>验收标准</dt>
<dd>跑出至少一个"该标准报错、另一个标准不报错"的对比结果,对照
<dd>跑出至少一个"该标准报错、另一个标准不报错"的对比,对照
<a class="filelink" target="_blank" href="../../VERSION_NOTES.md">docs/VERSION_NOTES.md</a> §2</dd>
<dt>基础知识 · 参考</dt>
<dd><a class="filelink" target="_blank" href="../../../tools/std_probe.py">tools/std_probe.py</a> ·
<a class="filelink" target="_blank" href="../../VERSION_NOTES.md">docs/VERSION_NOTES.md</a></dd>
<dd><a class="filelink" target="_blank" href="../../../tools/std_probe.py">tools/std_probe.py</a></dd>
</dl>
</div>
</section>
@@ -395,10 +345,10 @@ cmake --build build # 144 个目标全绿</code></pre>
<div class="verify-box">
<h4>验收</h4>
<pre><code class="bash" data-trim>cmake --build build --target all # Part1144 个目标全绿</code></pre>
<p>组提交一句话分工说明 + 至少 1 条 ERRATA 坑点讲解</p>
<p>人完成构建全绿 + 2 条 ERRATA 坑点讲解;PRETEST 结果已归档(决定后续调速)</p>
</div>
<p class="footer-note"><small>明天 Day2 进入 Qt项目结构 / 信号槽 / 控件 / 布局与 QSS ——
大纲:<a class="filelink" href="../OUTLINE.md">docs/teaching/OUTLINE.md</a></small></p>
<p class="footer-note"><small>明天 Day2 进入 Qt概述 / 创建项目 / 第一个程序 / 信号槽 → 计算器 ——
大纲:<a class="filelink" href="../OUTLINE_4DAY.md">docs/teaching/OUTLINE_4DAY.md</a></small></p>
<p><a class="filelink" href="index.html">返回目录</a> · <a class="filelink" href="day2.html">下一天 →</a></p>
</section>