Files
scuc-qt-course/docs/teaching/slides/day1.html
T
张宗平 9765865d13 Day1 C++ 回顾补一小节:C++11/14/17/20+ 新标准巡礼
原「C++ 环境搭建/高级程序回顾」只覆盖语言老知识点(namespace/重载/引用/
虚析构/模板),没有让学员感受到 C++ 这些年一直在大幅进化。新增一个概念性
知识点(无配套代码,同 Vcpkg 那一条的先例):按标准列出 C++11→20 的核心
新特性(auto/智能指针/移动语义/lambda → concepts/ranges/协程/模块),
并提醒"新标准≠生产环境能直接用",挂钩本仓库自身的 C++17 基线选择和
tools/std_probe.py。OUTLINE.md 表格行/核心概念条目与 day1.html 新增幻灯片
一一对应。
2026-07-02 16:41:48 +08:00

418 lines
20 KiB
HTML
Raw 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++ 回顾/工具链</h3>
<p class="module-badge">C++/Qt 方向实训 · 第 1 / 5 天 · 对齐官方方案书 Day1</p>
<ul>
<li>模块 A(3 课时):团队建设 / 敏捷 Scrum / C++ 在企业中的应用(讨论型,无编码)</li>
<li>模块 B(3 课时):C++ 环境搭建 / 高级程序回顾 / CMake / Vcpkg(压缩讲解)</li>
</ul>
<p><small>本教案假定学员已掌握 C++ 基础语法与 OOP 概念——方案书对今天下午的
官方定位是"回顾和提升",不是零基础教学。今天开始的 5 天覆盖方案书 C++方向
Day1–5 全部课堂内容,Day6–10 是纯项目实作。</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>
</div>
</section>
<!-- ===================== 模块 A:讲 ===================== -->
<section>
<section>
<p class="module-badge">模块 A · 讲授 35min</p>
<h2>团队建设 / 敏捷 Scrum / C++ 企业应用 <span class="tag tag-lecture"></span></h2>
<ul>
<li>团队建设与文化、实训安排与考评要求</li>
<li>项目开发过程管理全景(JIRA / Git / OASIS / Wiki</li>
<li>敏捷 Scrum 项目开发管理</li>
<li>C++ 在企业中的应用</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>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>需求分析→需求评审→项目研发/代码实现→阶段评审→项目测试/交付——每个环节都有明确的
"评审"节点把关,不是写完代码就结束,这就是接下来 Day6–10 项目实作要走的完整流程。</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>
<ul>
<li>JIRA(任务跟踪)+ Git(版本管理)+ Wiki 知识库 + OASIS 绿洲实训管理平台,四个工具
分别对应"谁在做什么/代码怎么变化/知识怎么沉淀/进度怎么被看到"四个不同维度,缺一个都会
让协作出现盲区。</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>
<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/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>
</ul>
</div>
<p><small>出处:仓库根 <a class="filelink" target="_blank" href="../../../CMakeLists.txt">CMakeLists.txt</a></small></p>
</section>
<section>
<h3>Vcpkg 包管理器(概念,无演示) <span class="tag tag-lecture"></span></h3>
<div class="concept-box">
<h4>核心概念</h4>
<ul>
<li>C++ 生态的包管理器,解决"第三方库怎么装、怎么被 CMake 找到"的问题——一次
<code>vcpkg install</code>,配合 CMake 的 toolchain 文件,<code>find_package</code>
就能自动找到头文件和库。</li>
</ul>
</div>
<div class="pitfall-box">
<h4>常见的坑</h4>
<ul>
<li>不是所有第三方库都必须用包管理器装——本仓库用的是"隔离 Qt 手动装"
<code>tools/install_qt_host.sh</code>)而非 vcpkg,两种思路都要认识:包管理器省心但
引入额外工具链,手动隔离装则精确控制版本/路径,各有取舍。</li>
</ul>
</div>
<div class="verify-box">
<h4>缺口说明</h4>
<p>本仓库暂无 vcpkg 可运行示例——安装真实 vcpkg 工具链超出最小示例范畴,此处仅作概念介绍。</p>
</div>
</section>
</section>
<!-- ===================== 模块 B:练 ===================== -->
<section>
<section>
<p class="module-badge">模块 B · 练习 95min</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>
<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> ·
<a class="filelink" target="_blank" href="../../VERSION_NOTES.md">docs/VERSION_NOTES.md</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>每组提交一句话分工说明 + 至少 1 条 ERRATA 坑点讲解。</p>
</div>
<p class="footer-note"><small>明天 Day2 进入 Qt:项目结构 / 信号槽 / 控件 / 布局与 QSS ——
大纲:<a class="filelink" href="../OUTLINE.md">docs/teaching/OUTLINE.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>