友元函数是用friend关键字声明的非成员函数,可访问类的私有和保护成员。例如printData能访问MyClass的私有数据data,虽提升灵活性但破坏封装性。
在C++中,友元函数和友元类是一种特殊的机制,允许外部函数或类访问某个类的私有(private)和保护(protected)成员。这种设计初衷是为了提高灵活性,尤其在运算符重载、工具函数封装等场景下非常有用。但与此同时,它也打破了面向对象编程中“封装”的基本原则,使用不当容易带来维护性和安全性问题。
友元函数不是类的成员函数,但它被授予访问该类所有成员(包括私有和保护成员)的权限。通过在类内部使用 friend 关键字声明即可。
例如:
class MyClass {
private:
int data;
public:
MyClass(int d) : data(d) {}
// 声明友元函数
friend void printData(const MyClass& obj);
};
// 友元函数定义
void printData(const MyClass& obj) {
std::cout << "Data: " << obj.data << std::endl; // 可直接访问私有成员
}
这里,printData 虽然不是 MyClass 的成员,却能访问其私有成员 data。这在实现输入输出操作符重载时很常见,比如 operator 经常被设为友元。
当一个类被声明为另一个类的友元时,它可以访问后者的所有私有和保护成员。这适用于两个类之间存在紧密协作关系的场景。
class SecretBox {
private:
std::string secret;
public:
SecretBox(const std::string& s) : secret(s) {}
// 声明 FriendClass 为友元类
friend class KeyHolder;
};
class KeyHolder {
public:
void revealSecret(const SecretBox& box) {
std::cout << "Secret is: " << box.secret << std::endl; // 合法
}
};
KeyHolder 类可以自由访问 SecretBox 的私有数据,体现了一种高度信任的关系。但这也意味着两者耦合度极高,修改一个可能影响另一个。
封装是面向对象的核心原则之一,目的是隐藏实现细节,仅暴露必要的接口。而友元机制直接绕过了这一限制。
虽然友元有风险,但在某些情况下仍是必要且优雅的解决方案。
基本上就这些。友元不是洪水猛兽,而是双刃剑。掌握好使用的边界,才能发挥其便利而不陷入陷阱。不恰当地追求“完全私有”可能让设计僵化,但盲目使用友元也会让封装
形同虚设。关键在于权衡与清晰的设计意图表达。
# 工具
# c++
# 面向对象编程
# 封装性
# 运算符
# 面向对象
# 封装
# 成员函数
# 接口
# private
# protected
# 运算符重载
# operator
# 对象
# 重构
# 低代码
# 设为
# 这是
# 迭代
# 这一
# 是一种
# 洪水猛兽
# 但在
# 形同虚设
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Win10如何卸载WindowsDefender_Win10卸载Defender教程【方法】
Win11怎么更改盘符_Win11磁盘管理修改驱动器号【步骤】
如何在JavaScript中动态拼接PHP的base_url与jQuery变量
MAC如何启用访达侧边栏显示_MAC Finder偏好设置与常用目录添加【教程】
XSLT怎么生成动态的HTML属性名和标签名
Win11键盘快捷键大全_Windows 11常用高效快捷键汇总【技巧】
如何在JavaScript中动态拼接PHP的base_url与前端变量
如何更改Windows资源管理器的默认启动位置?(快速访问/此电脑)
Go 语言标准库为何不提供泛型 Contains 方法:设计哲学与类型系统约束
为什么Go建议使用error接口作为错误返回_Go Error接口设计原因说明
Win11怎么设置声音输出设备_Windows11音量合成器单独调节应用
Win11任务栏怎么调到左边_Win11开始菜单居左设置教程【步骤】
VSC怎么在PHP中调试MySQL_数据库交互排查技巧【教程】
PowerShell怎么创建复杂的XML结构
PhpStorm怎么调试PHP代码_PhpStorm断点设置与调试启动步骤【指南】
如何在Golang中实现并发消息队列消费者_Golang channel消息消费实践
c++怎么调用nana库开发GUI_c++ 现代风格窗口组件与事件处理【实战】
如何在 Go 项目开发中正确处理本地包导入与远程模块路径的一致性问题
WindowsUSB驱动安装异常怎么办_USB驱动重建与恢复教程
如何在Golang中处理JSON字段缺失_Golangjson解析字段校验方法
Windows10电脑怎么设置自动连接WiFi_Win10无线网络属性勾选
c++怎么实现大文件的分块读写_c++ 文件指针seekp与seekg偏移控制【方法】
Win11输入法选字框不见了怎么办_Win11输入法修复与重置【教程】
windows 10应用商店区域怎么改_windows 10微软商店切换地区方法
Python邮件系统自动化教程_批量发送解析与模板应用
PHP主流架构如何处理会话管理_Session与Cookie【技巧】
Windows10系统怎么查看设备管理器_Win10快捷键Win+X菜单使用
Windows10任务栏图标变成白色文件_Win10重建图标缓存修复方法
C++ STL算法库怎么用?C++常用算法函数(sort, find)教程【效率提升】
Win11怎么开启HDR模式_Windows 11高动态范围显示设置指南【详解】
Win11怎么忘记WiFi网络_Win11删除已保存无线连接【教程】
Win10怎么创建桌面快捷方式 Win10为应用创建快捷方式【步骤】
c++ nullptr与NULL区别_c++11空指针规范
Win10怎样清理C盘浏览器缓存_Win10清理浏览器缓存步骤【步骤】
Win10怎样卸载DockerDesktop_Win10卸载DockerDesktop步骤【步骤】
为什么本地php环境运行php脚本卡顿_php执行效率优化方法与设置【说明】
php在Linux怎么部署_LNMP环境搭建PHP服务的详细指南【指南】
微信企业付款回调PHP怎么接收_处理企业付款异步通知数据教程【教程】
如何解决Windows时间不准的问题?(自动同步设置)
Win11怎么更改任务栏颜色_Windows11个性化重音色设置
C++中的std::shared_from_this有什么用?C++安全获取this的shared_ptr【智能指针】
PHP怎么接收URL中的锚点参数_获取#后面参数值的技巧【详解】
TestNG的testng.xml配置文件怎么写
php订单日志怎么导出excel_php导出订单日志到表格教程【教程】
php能跑在stm32上吗_php在stm32微控制器上的移植方法【介绍】
Win11怎么更改账户头像_Windows 11自定义用户头像图片设置【步骤】
MAC的“接续互通”功能无法使用怎么办_MAC检查蓝牙、Wi-Fi和相同Apple ID登录
Flask 表单数据通过 SMTP 发送邮件的完整实现教程
Python项目回滚策略_发布安全说明【指导】
Go语言中正确反序列化多个同级XML元素为结构体切片的方法
2025-12-03
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。