当前位置: 首页 > news >正文

C++中的友元 之六

在 C++ 从 C++11 到 C++23 的演进过程中,虽然“友元”的核心定义(即特权访问)没有发生翻天覆地的改变,但在语法灵活性模板化处理以及封装安全性上确实有显著的增强。

我们可以从以下四个维度来看 C++ 对友元的改进:


1. 语法简化:不再强制要求 class/struct 关键字 (C++11)

在传统的 C++(C++98)中,声明一个类为友元时,必须带上 classstruct 关键字。

  • 旧写法: friend class Vector;
  • 新写法: friend Vector;

这个改进看似微小,但它解决了类型别名(typedef/using)无法作为友元的问题。

为什么这很重要?

在现代 C++ 中,我们经常使用 using 来定义复杂的类型。在 C++11 之前,你不能直接把一个别名设为友元,现在可以了:

using GlobalMatrix = Matrix<double, 4, 4>;class HardwareScanner {friend GlobalMatrix; // C++11 允许,旧版本报错
};

2. 模板友元的增强 (C++11)

这是现代 C++ 中最实用的改进之一:模板参数友元

在旧标准中,你无法将一个模板参数声明为友元,因为编译器在解析类定义时不知道 T 到底是个什么东西。C++11 引入了 friend T; 的语法。

应用场景:单例模式或工厂模式

假设你正在写一个库,你想让用户定义的任意类 T 能够访问你系统内部的某个私有构造函数:

template <typename T>
class AccessGrantor {
private:AccessGrantor() {} // 私有构造函数friend T; // 将模板参数设为友元
};class UserClass : public AccessGrantor<UserClass> {// 因为是友元,UserClass 可以访问 AccessGrantor 的私有构造函数
};

3. 约束友元:与 Concept (特性) 的结合 (C++20)

C++20 引入了 Concepts(概念),这改变了我们编写模板的方式。虽然友元的声明语法没变,但我们可以通过 requires 子句来限制谁能成为友元,或者在友元函数中使用约束。

这解决了“友元过于强大”的问题。你可以声明一个友元函数,但要求该函数的操作数必须满足某些条件(比如必须是可增加的 std::incrementable)。


4. 隐藏友元 (Hidden Friends) 的流行

这并不是语法上的强制改变,而是现代 C++(尤其是高度依赖模板的库,如标准库本身)推崇的一种设计模式

什么是隐藏友元?

直接在类定义内部定义(不仅仅是声明)友元函数。

class Fraction {int num, den;
public:// 这就是一个隐藏友元friend bool operator==(const Fraction& lhs, const Fraction& rhs) {return lhs.num == rhs.num && lhs.den == rhs.den;}
};

改进了什么?

  1. 编译速度:隐藏友元只能通过 ADL(参数依赖查找) 找到。编译器不需要在全局命名空间里搜索成千上万个函数,只需查找参数所属的类即可。
  2. 避免污染:它不会被非相关的类型意外调用,减少了命名冲突的概率。
  3. 更强的封装:虽然它是友元,但它在类的作用域外是不可见的(除非通过它的参数类型去触发)。

总结:C++ 友元的进化趋势

维度 传统 C++ (98/03) 现代 C++ (11/17/20/23)
声明灵活性 必须明确指定 class/struct 支持 using 别名和模板参数
查找机制 倾向于全局声明 倾向于 Hidden Friends (ADL 查找)
模板支持 难以对模板实例授权 支持对具体的模板参数 T 授权
安全性 “全有或全无” 结合 Concepts 实现有条件的友元功能

下一步建议

由于你从 C# 转过来,C# 的 internal 关键字在 C++ 中对应的其实就是这种“精心设计的友元关系”。

http://www.jsqmd.com/news/415505/

相关文章:

  • 五款免费AI视频生成神器,效果炸裂!
  • STM32F103C8T6 驱动 180° 舵机(SG90)超详细教程
  • 【开题答辩全过程】以 共享单车使用情况预测模型的设计与实现为例,包含答辩的问题和答案
  • C++中的友元 之五
  • 互斥锁
  • 数据库的应用-第一天
  • P3035 [USACO11DEC] Umbrellas for Cows S 题解
  • AI Compose Commit:用 AI 智能重构 Git 提交工作流
  • 题解:P11567 建造军营 II
  • C++中的友元 之四
  • 哈萨克斯坦旅游出行笔记
  • 2026年广州名士表手表维修推荐榜单评测:非官方维修网点服务与售后中心选择指南 - 十大品牌推荐
  • Gin 框架中的规范响应格式设计与实现
  • Computer Vision (Prof. Andreas Geiger, University of Tbingen)
  • QOJ #7324. Eulerian Orientation 题解
  • 2026年广州摩凡陀手表维修推荐榜单:非官方维修网点服务评测与选择指南 - 十大品牌推荐
  • 本次AIGC论文助手精心整理并发布了十大高效AI写作工具的详细专业测评分析
  • 最可爱の树剖姐姐
  • 距国自然申报仅剩20天!您确定自己的本子“读懂“2026新规了吗?
  • C++中的友元 之三
  • C++中的友元 之二
  • AI:RAG
  • NCE-Flow 是什么?新概念英语开源学习系统安装与使用教程
  • 远方好物:4年暴涨200万会员,GMV破20亿!它不投广告、不搞流量,凭什么杀出重围?
  • chili3d 是什么?开源在线3D建模工具安装与使用教程
  • 专家安全测试_动态安全服务_移动 APP 漏洞扫描修复工具
  • 对话“五度妙笔”|小核酸药物市场规模与投资前景分析
  • AI Coding
  • 零基础转行网络安全运维?收藏这篇,学习顺序搞错=白费功夫!
  • 记录在vmware虚拟机Ubuntu22.04上编译doom