Files
scuc-qt-course/tools/wiki_data/bodies/58954457.json
T
张宗平 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 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"}}