Files
张宗平 0f81edcc74 幻灯片按 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 失效
2026-07-05 12:49:44 +08:00

368 lines
17 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<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">
<link rel="stylesheet" href="reveal/plugin/highlight/monokai.css">
<link rel="stylesheet" href="custom.css">
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<h1>Day 1</h1>
<h3>开训 + C++ 回顾与提升(全天 C++)</h3>
<p class="module-badge">C++/Qt 方向实训 · 第 1 / 4 个讲授日 · 对齐 2026-07 新版 10 天安排</p>
<ul>
<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 概念——今天定位是"回顾和提升",
不是零基础教学。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>OOP 回顾开讲前:10 分钟摸底测验</h4>
<p>受众假设要实测——用 <a class="filelink" target="_blank" href="../PRETEST.md">docs/teaching/PRETEST.md</a>
(10 题、10 分钟、A/B 平行卷)测一次,按结果决定回顾环节推进速度(分层预案见该文件)。</p>
</div>
</section>
<!-- ===================== 上午:讲 ===================== -->
<section>
<section>
<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>C++ 常用技术和框架(讲座)</li>
<li>开发环境搭建 + Makefile/CMake 项目构建</li>
<li>PRETEST 摸底(10min)→ 面向对象基础回顾(类/对象/封装)</li>
</ul>
</section>
<section>
<h3>C++ 常用技术和框架(讲座) <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念——C++ 的四大应用版图</h4>
<ul>
<li><b>桌面客户端</b>:Qt(本次实训主线)、跨平台 GUI;</li>
<li><b>服务端/基础设施</b>:高性能网络服务、数据库引擎、游戏服务器;</li>
<li><b>嵌入式/车载</b>:资源受限环境里 C++ 仍是第一梯队选择;</li>
<li><b>游戏/图形</b>UE 引擎、渲染管线。</li>
</ul>
</div>
<div class="concept-box">
<h4>而且它还在进化</h4>
<ul>
<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>
</section>
<section>
<h3>CMake:用本仓库当教材 <span class="tag tag-lecture"></span></h3>
<pre><code class="bash" data-trim>cmake -S . -B build -G Ninja -DBUILD_QT_PART=OFF -DCMAKE_BUILD_TYPE=Debug
cmake --build build # 144 个目标全绿</code></pre>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>CMake 是"生成构建系统的工具"而不是构建系统本身:<code>cmake -S -B</code>
<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> 却没重新配置:大多数改动 CMake 会自动侦测,
但换生成器/清缓存后需要重新走一次 <code>-S -B</code></li>
</ul>
</div>
<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>★ 编译错误 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><code>error:</code> 带行号 = 编译期问题(语法/类型/没声明)——回代码里查那一行;
<code>undefined reference</code> 无行号 = 链接期问题(有声明没定义/缺库/缺目标文件)——
查"定义在哪、链没链进来",回头检查语法是南辕北辙。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>中初级学员见到 <code>undefined reference</code> 的第一反应是检查拼写和语法——方向就错了。
明天 Qt 的"忘写 <code>Q_OBJECT</code>"报的正是链接错误,且报错完全不提宏,记住今天这页。</li>
</ul>
</div>
</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>
<!-- ===================== 上午:练 ===================== -->
<section>
<section>
<p class="module-badge">上午 · 课堂练习 11:00–12:00(工程师指导、答疑)</p>
<h2>动手:走一遍真实构建流程 <span class="tag tag-practice"></span></h2>
</section>
<section>
<div class="task-card">
<h4>任务卡 1 · 走一遍真实构建流程 <span class="tag tag-practice"></span></h4>
<dl class="task-spec">
<dt>目标</dt>
<dd>独立完成本仓库 Part1 的配置+构建,不看着教师操作</dd>
<dt>验收标准</dt>
<dd><code>cmake -S . -B build -G Ninja -DBUILD_QT_PART=OFF</code> 配置成功;
<code>cmake --build build</code> 144 个目标全绿;能说出 <code>option(BUILD_QT_PART)</code> 的作用</dd>
<dt>基础知识 · 参考</dt>
<dd><a class="filelink" target="_blank" href="../../../CMakeLists.txt">仓库根 CMakeLists.txt</a> ·
<span class="ext-ref">CMake 官方文档 Tutorial(选读·需联网)</span></dd>
</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>
<dt>验收标准</dt>
<dd>能用一句话向同组同学解释清楚,不能只念代码</dd>
<dt>基础知识 · 参考</dt>
<dd><a class="filelink" target="_blank" href="../../ERRATA.md">docs/ERRATA.md</a></dd>
</dl>
</div>
</section>
<section>
<div class="task-card">
<h4>任务卡 3(选做)· 版本探针 <span class="tag tag-practice"></span></h4>
<dl class="task-spec">
<dt>目标</dt>
<dd><code>tools/std_probe.py</code> 验证一个标准版本差异点</dd>
<dt>验收标准</dt>
<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></dd>
</dl>
</div>
</section>
</section>
<!-- ===================== 收尾 ===================== -->
<section>
<h2>当日产出验证</h2>
<div class="verify-box">
<h4>验收</h4>
<pre><code class="bash" data-trim>cmake --build build --target all # Part1144 个目标全绿</code></pre>
<p>每人完成构建全绿 + 2 条 ERRATA 坑点讲解;PRETEST 结果已归档(决定后续调速)。</p>
</div>
<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>
</div>
</div>
<script src="reveal/reveal.js"></script>
<script src="reveal/plugin/highlight/highlight.js"></script>
<script>
Reveal.initialize({
hash: true, controls: true, progress: true, center: true, slideNumber: true,
plugins: [ RevealHighlight ]
});
</script>
</body>
</html>