0

0

C++中的friend class与friend function是什么?(如何合理控制私有权限)

尼克

尼克

发布时间:2026-03-09 12:38:03

|

744人浏览过

|

来源于php中文网

原创

friend class 在特定协作场景下合理使用可避免暴露接口,如 iterator 访问 container 私有数组;需前向声明、不传递、不继承、增加头文件依赖;friend function 适合对称操作如 operator。

c++中的friend class与friend function是什么?(如何合理控制私有权限)

friend class 会打破封装,但只在特定协作场景下值得用

它让另一个类能直接访问当前类的所有私有成员,不是为了偷懒绕过访问控制,而是解决两个紧密耦合类之间“不得不共享内部状态”的问题。比如 Iterator 类需要遍历 Container 的底层数组,而这个数组必须是私有的——这时把 Iterator 声明为 Containerfriend class,比暴露 get_raw_data() 或把数组设为 public 更干净。

常见错误现象:friend class B; 写在 A 类定义里,但编译报错说 B 未定义——这是因为 B 类型名在声明时还不可见,得提前声明 class B;(前向声明)。

  • 只能在类定义内部声明,不能在类外补加
  • 不具有传递性:A 是 B 的 friend,B 是 C 的 friend,不等于 A 能访问 C 的私有成员
  • 不会继承:派生类不会自动获得基类 friend 的权限
  • 头文件依赖变重:friend class X; 意味着你得 #include X 的定义,或至少前向声明

friend function 适合做对称操作,比如 operator

当某个函数逻辑上不属于任何一方、又需要访问双方私有成员时,friend 函数是唯一选择。最典型的是流输出运算符:operator 左操作数是 <code>std::ostream&,不可能把它塞进你的类里;但它又得读你的私有字段,所以必须声明为 friend

使用场景举例:实现两个自定义类的相等比较 operator==(const A&, const B&),且双方都有不可公开的内部标识字段。

立即学习C++免费学习笔记(深入)”;

SumiNote
SumiNote

一款服务留学生的AI学习神器

下载
  • 声明时写全签名:friend std::ostream& operator
  • 定义可以放在类外(通常在 .cpp 里),不用加 friend 关键字
  • 如果函数模板要成为 friend,需显式指定模板参数或使用友元模板声明,否则容易因 ADL 失效而调用不到
  • 避免把普通工具函数(如 validate())设为 friend——它本该通过 public 接口完成工作

别用 friend 绕过设计缺陷,否则私有字段形同虚设

看到 “我需要访问 private 成员” 就加 friend,大概率说明类职责没划清。比如一个 Database 类把连接句柄藏成私有,结果所有业务类都申请成为它的 friend 去执行 SQL——这其实是 Database 缺少足够粒度的 public 方法(如 execute_query()),而不是 friend 用得不够多。

容易踩的坑:

  • 测试类(如 MyClassTest)不该是 friend:应测 public 行为,而非钻进去检查私有字段值
  • 把整个第三方库的命名空间设为 friend(friend namespace boost;)——C++ 不支持,而且极其危险
  • 误以为 friend 提升性能:它只是取消访问检查,不影响内联、拷贝或内存布局
  • 在模板类中声明 friend 时,若未用 template<typename t></typename> 显式关联,会导致特化版本无法访问

替代方案往往更可持续:组合 + 精细接口 > 暴露内部

多数时候,与其拉一个 friend 进来,不如在类里加一个受控的访问入口。比如把 std::vector<int> data_;</int> 私有成员,换成 const std::vector<int>& raw_data() const { return data_; }</int> ——既不破坏封装,又满足只读需求。

性能影响很小:返回 const 引用几乎零开销;如果担心别名问题,可用 std::span<const int></const> 替代(C++20)。

  • 优先提供 const 访问器,而非非 const 的 getter
  • std::optional<t></t> 或状态码表达“可能不存在”的访问结果,比返回裸指针安全
  • 对调试用途的私有状态,考虑用宏控制是否编译进 release 版本,而不是靠 friend 开后门

真正难处理的是跨模块的深度协作——比如解析器和语法树节点。这时候 friend 不是捷径,而是明确的契约:你得同步维护双方的内部变更,稍有不慎就崩。这种耦合,写注释比写代码还重要。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1876

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

636

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2382

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

47

2026.01.19

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

829

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

28

2025.12.06

function是什么
function是什么

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果。本专题为大家提供function是什么的相关的文章、下载、课程内容,供大家免费下载体验。

498

2023.08.04

js函数function用法
js函数function用法

js函数function用法有:1、声明函数;2、调用函数;3、函数参数;4、函数返回值;5、匿名函数;6、函数作为参数;7、函数作用域;8、递归函数。本专题提供js函数function用法的相关文章内容,大家可以免费阅读。

166

2023.10.07

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

59

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11万人学习

C 教程
C 教程

共75课时 | 5.3万人学习

C++教程
C++教程

共115课时 | 21.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号