news 2026/6/21 22:22:13

《你真的了解C++吗》No.028:友元(friend)的必要性与边界——为什么它不是对封装的破坏?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《你真的了解C++吗》No.028:友元(friend)的必要性与边界——为什么它不是对封装的破坏?

《你真的了解C++吗》No.028:友元(friend)的必要性与边界——为什么它不是对封装的破坏?

导言:封装的“后门”还是“窗户”?

如果一个类将所有成员都设为private,它确实非常安全,但也可能变得非常孤立。有些操作(如操作符重载或跨类协作)必须访问内部数据才能高效运行。

友元机制允许一个类授予特定的函数或类“通行证”,让它们能够访问自己的非公有成员。


一、 友元存在的物理理由:操作符重载

为什么我们需要友元?最经典的例子是operator<<的重载。

如果你想让你的类支持std::cout << myObj;,你不能把它写成成员函数。因为成员函数的第一个参数必须是类对象本身(this),这意味着你只能写成myObj << std::cout;,这违背了直觉。

为了支持正确的语法,你必须写一个全局函数:

classPoint{intx,y;public:Point(intx,inty):x(x),y(y){}// 声明全局函数为友元friendstd::ostream&operator<<(std::ostream&os,constPoint&p);};// 全局函数实现std::ostream&operator<<(std::ostream&os,constPoint&p){os<<"("<<p.x<<", "<<p.y<<")";// 直接访问私有变量 x, yreturnos;}

二、 友元破坏了封装吗?

这是一个常见的误区。事实上,友元不仅没有破坏封装,反而增强了封装。

  1. 主动权在类自己手中:你是被动地被“窥探”吗?不,是类自己声明了谁是它的朋友。权限的授予是单向且显式的。
  2. 避免暴露 Setter/Getter:如果没有友元,为了让外界(比如一个 Matrix 类)操作内部数据,你可能不得不被迫把数据设为public或者提供公有的set/get。这样所有人都能改它了。
  3. 精确授权:通过友元,你只把权限给了特定的“某个人”,而对全世界其他所有人依然保持封闭。

三、 友元的四条铁律(编译器视角)

友元的规则非常特殊,它们不遵循普通的继承逻辑:

  1. 友元关系不可逆:类 A 是类 B 的友元,并不代表 B 是 A 的友元。
  2. 友元关系不可传递:你的朋友的朋友,不是你的朋友。
  3. 友元关系不可继承:基类的友元在派生类中没有特权。老子的朋友不一定是儿子的朋友。
  4. 位置无关:在类定义中,friend声明写在publicprotected还是private下面效果是一样的,它不受访问控制符的影响。

四、 友元类与 Pimpl 模式

在复杂的工程中,我们常使用**友元类(Friend Class)**来实现“代理”或“逻辑分离”。
例如,一个Container类可能将Iterator类设为友元,这样迭代器就能高效地遍历容器的私有链表结构,而不需要将链表节点暴露给用户。


总结:有选择的信任

  • 友元是类的一种显式授权,用于解决某些全局函数或协作类必须访问私有数据的问题。
  • 它通过限制“知情权”的范围,避免了由于滥用public导致的封装劣化。
  • 准则:不到万不得已不用友元,但一旦需要,它比增加公有访问接口更安全。

下一篇预告:结束了继承与权限的探讨,我们要聊聊一个极其微小但影响深远的语法:为什么在虚函数后面写上= 0叫纯虚函数?而如果不小心写错了签名,编译器会怎么整你?

➡️《你真的了解C++吗》No.029:虚函数表中的“意外”——函数签名不匹配导致的重写失败。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/21 10:46:53

全网最全8个AI论文软件,研究生高效写作必备!

全网最全8个AI论文软件&#xff0c;研究生高效写作必备&#xff01; 论文写作的“隐形助手”&#xff0c;你真的了解吗&#xff1f; 在研究生阶段&#xff0c;论文写作不仅是学术能力的体现&#xff0c;更是时间与精力的双重挑战。随着人工智能技术的不断进步&#xff0c;AI工具…

作者头像 李华
网站建设 2026/6/15 18:57:07

SGMICRO圣邦微 SGM3209YS8G/TR SOP-8 电荷泵

特性 输入电压范围:3V至18V输出电流:100mA 使能引脚上的下拉电阻:600kO2 可编程振荡器频率:120kHz至1.25MHz 无需外部二极管 低输出阻抗:在lout20mA时为15O(典型值) CMOS结构 工作温度范围:-40C至85C提供绿色TDFN-2x2-8L和SOIC-8封装

作者头像 李华
网站建设 2026/6/15 11:20:20

SGMICRO圣邦微 SGM41511YTQF24G/TR TQFN24 电池管理

功能特性 高效率&#xff0c;1.5MHz&#xff0c;同步降压充电器在5V输入下&#xff0c;1A电流时充电效率为93% .从5V输入以2A输出时充电效率达91% .优化适用于USB电压输入(5V) .可选PFM模式以实现轻载效率支持USB即插即用(OTG)模式(升压模式)。 .最高输出1.2A的升压转换器 .在0…

作者头像 李华
网站建设 2026/6/19 19:56:52

深入解析Scikit-learn模型API:超越基础用法的高级实践

深入解析Scikit-learn模型API&#xff1a;超越基础用法的高级实践 引言&#xff1a;为何需要深入理解Scikit-learn API&#xff1f; Scikit-learn作为Python机器学习领域的事实标准库&#xff0c;其简洁统一的API设计备受赞誉。大多数开发者熟悉基础的fit()、predict()、tran…

作者头像 李华
网站建设 2026/6/13 14:06:49

2026短视频爆梗音效大全:10个免费素材网站推荐

根据《2025中国短视频内容生态发展报告》显示&#xff0c;短视频内容中音效的使用频率同比提升了35%&#xff0c;优质的爆梗音效能让视频的用户互动率提高28%。对于短视频创作者来说&#xff0c;找到免费又热门的爆梗音效是提升内容质量的关键一步。接下来&#xff0c;我们就来…

作者头像 李华