Files
张宗平 13b3ebbe14 课程代码仓库初始化:Part1 (144) + Part3 (29) 全量生成与验证
把川大 wiki「02.Qt方向」课程代码整理为 CMake 管理的可编译运行项目。

Part1 C/C++ 强化 (p01/, 144 目标, host gcc/g++ 构建, 全绿):
- 修复全部编译失败:补 <cstring>/<fstream>/<iomanip>/<vector> 等缺失头
  (common_fix + infer_stl_includes 自动检测注入)、修正 pause() 壳注入
  (改检测已转换后的 pause 调用)、namespace 提升出函数体、const 成员函数
  正确性、dedupe 不再破坏函数重载集、K&R 隐式 int / 动态异常规范等
  C++17 移除特性的可编译等价改写。
- 目录采用深缩写 p01/ch04/s03/ (原 part1_cpp/ch04_class_object/03_ctor_dtor)。

Part3 Qt 桌面 (p03/, 29 目标, 隔离 Qt 5.14.2 构建, 全绿):
- gen_part3.py: Qt 外壳模板 (main+QApplication+show, QTimer 自动退出便于
  offscreen 验证)、AUTOMOC + .moc include、rewrite_* 处理散文混入/重载/
  资源依赖、生成占位 png/gif + .qrc + rundata 样例数据。
- 修正 QLable 笔误、全角分号、.→->、Windows 路径、QApplication 阻塞事件
  循环改为 QCoreApplication 等。

任务1 概念/版本验证:
- tools/std_probe.py: 跨 -std= 编译探针 (--pedantic-errors 让已废除特性硬失败)。
- tools/demo_versions/: K&R 隐式 int、三目左值、void* 转换、enum 赋整、
  const 经指针、动态异常规范 共 6 个跨版本演示。
- docs/VERSION_NOTES.md: 每条「原文说法→C17/C++17 是否成立→何版本成立→已验证」。

文档: 顶层 README、docs/SOURCE_PAGES.md (页面→目录映射)、
docs/ERRATA.md (Part1 修正)、docs/ERRATA_part3.md (Part3 修正)。
另修复 tools/run.sh / run_qt.sh 的 ${1:?...} 引号语法 bug。

隔离 Qt 验证: ldd 0 系统 Qt 引用; 173/173 目标全绿; p03 offscreen 运行通过。
2026-06-30 14:16:55 +08:00

1 line
6.0 KiB
JSON
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"id":"58954457","type":"page","status":"current","title":"05.友元","version":{"by":{"type":"known","username":"ethanliu","userKey":"2c90931b6cfb654f016d5c69becc0001","profilePicture":{"path":"/images/icons/profilepics/default.svg","width":48,"height":48,"isDefault":true},"displayName":"刘浩","_links":{"self":"https://wiki.suncaper.net/rest/api/user?key=2c90931b6cfb654f016d5c69becc0001"},"_expandable":{"status":""}},"when":"2022-07-09T01:51:24.000Z","message":"","number":1,"minorEdit":false,"hidden":false,"_links":{"self":"https://wiki.suncaper.net/rest/experimental/content/58954457/version/1"},"_expandable":{"content":"/rest/api/content/58954457"}},"body":{"storage":{"value":"<ac:layout><ac:layout-section ac:type=\"two_right_sidebar\"><ac:layout-cell><h2><span>4.5 </span>友元</h2><p>类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部<span>(</span>作用域之外<span>)</span>访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?</p><p>解决方法是使用友元函数,友元函数是一种特权函数,<span>c++</span>允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解:</p><p>比如你的家,有客厅,有你的卧室,那么你的客厅是<span>Public</span>的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。</p><p>程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。</p><h3><span>4.5.1 </span>友元语法</h3><ul><li>friend关键字只出现在声明处</li><li>其他类、类成员函数、全局函数都可声明为友元</li><li>友元函数不是类的成员,不带<span>this</span>指针</li><li>友元函数可访问对象任意成员属性,包括私有属性</li></ul><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"aaa2d567-4d7c-48e8-af7d-361239d5af64\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[class Building;\n//友元类\nclass MyFriend{\npublic:\n\t//友元成员函数\n\tvoid LookAtBedRoom(Building& building);\n\tvoid PlayInBedRoom(Building& building);\n};\nclass Building{\n\t//全局函数做友元函数\n\tfriend void CleanBedRoom(Building& building);\n#if 0\n\t//成员函数做友元函数\n\tfriend void MyFriend::LookAtBedRoom(Building& building);\n\tfriend void MyFriend::PlayInBedRoom(Building& building);\n#else\t\n\t//友元类\n\tfriend class MyFriend;\n#endif\npublic:\n\tBuilding();\npublic:\n\tstring mSittingRoom;\nprivate:\n\tstring mBedroom;\n};\n\nvoid MyFriend::LookAtBedRoom(Building& building){\n\tcout << \"我的朋友参观\" << building.mBedroom << endl;\n}\nvoid MyFriend::PlayInBedRoom(Building& building){\n\tcout << \"我的朋友玩耍在\" << building.mBedroom << endl;\n}\n\n//友元全局函数\nvoid CleanBedRoom(Building& building){\n\tcout << \"友元全局函数访问\" << building.mBedroom << endl;\n}\n\nBuilding::Building(){\n\tthis->mSittingRoom = \"客厅\";\n\tthis->mBedroom = \"卧室\";\n}\n\nint main(){\n\n\tBuilding building;\n\tMyFriend myfriend;\n\n\tCleanBedRoom(building);\n\tmyfriend.LookAtBedRoom(building);\n\tmyfriend.PlayInBedRoom(building);\n\n\tsystem(\"pause\");\n\treturn EXIT_SUCCESS;\n}]]></ac:plain-text-body></ac:structured-macro><p><span> </span></p><table class=\"wrapped\"><colgroup><col /></colgroup><tbody><tr><td><p><span>    </span><strong>[</strong><strong>友元类注意<span>]</span></strong></p><p>1.友元关系不能被继承。</p><p>2.友元关系是单向的,类<span>A</span>是类<span>B</span>的朋友,但类<span>B</span>不一定是类<span>A</span>的朋友。</p><p>3.友元关系不具有传递性。类<span>B</span>是类<span>A</span>的朋友,类<span>C</span>是类<span>B</span>的朋友,但类<span>C</span>不一定是类<span>A</span>的朋友。</p></td></tr></tbody></table><p><strong>思考<span>: c++</span>是纯面向对象的吗?</strong></p><table class=\"wrapped\"><colgroup><col /></colgroup><tbody><tr><td><p>如果一个类被声明为<span>friend,</span>意味着它不是这个类的成员函数,却可以修改这个类的私有成员,而且必须列在类的定义中,因此他是一个特权函数。<span>c++</span>不是完全的面向对象语言,而只是一个混合产品。增加<span>friend</span>关键字只是用来解决一些实际问题,这也说明这种语言是不纯的。毕竟<span>c++</span>设计的目的是为了实用性,而不是追求理想的抽象。</p><p>                                                       --- Thinking in C++</p></td></tr></tbody></table><h3><span>4.5.2 </span>课堂练习</h3><table class=\"wrapped\"><colgroup><col /></colgroup><tbody><tr><td><p>请编写电视机类,电视机有开机和关机状态,有音量,有频道,提供音量操作的方法,频道操作的方法。由于电视机只能逐一调整频道,不能指定频道,增加遥控类,遥控类除了拥有电视机已有的功能,再增加根据输入调台功能。</p></td></tr></tbody></table></ac:layout-cell><ac:layout-cell><p><br /></p></ac:layout-cell></ac:layout-section></ac:layout>","representation":"storage","_expandable":{"content":"/rest/api/content/58954457"}},"_expandable":{"editor":"","view":"","export_view":"","styled_view":"","anonymous_export_view":""}},"extensions":{"position":"none"},"_links":{"webui":"/pages/viewpage.action?pageId=58954457","edit":"/pages/resumedraft.action?draftId=58954457","tinyui":"/x/2ZKDAw","collection":"/rest/api/content","base":"https://wiki.suncaper.net","context":"","self":"https://wiki.suncaper.net/rest/api/content/58954457"},"_expandable":{"container":"/rest/api/space/2CT","metadata":"","operations":"","children":"/rest/api/content/58954457/child","restrictions":"/rest/api/content/58954457/restriction/byOperation","history":"/rest/api/content/58954457/history","ancestors":"","descendants":"/rest/api/content/58954457/descendant","space":"/rest/api/space/2CT"}}