【C++入门】Cyber霓虹镜像城的跨域通行证 —— 【友元(friend)】跨类协作破坏封装性?友元函数与友元类为你架起特权桥梁!

⚡ CYBER_PROFILE ⚡
/// SYSTEM READY ///


WARNING \]: DETECTING HIGH ENERGY **🌊 🌉 🌊 心手合一 · 水到渠成** ![分隔符](https://i-blog.csdnimg.cn/direct/60a3de2294e9439abad47378e657b337.gif) |------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| | **\>\>\> ACCESS TERMINAL \<\<\<** || | [**\[ 🦾 作者主页 \]**](https://blog.csdn.net/fengtinghuqu520?spm=1000.2115.3001.5343) | [**\[ 🔥 C语言核心 \]**](https://blog.csdn.net/fengtinghuqu520/category_12955956.html) | | [**\[ 💾 编程百度 \]**](https://blog.csdn.net/fengtinghuqu520/category_13083835.html) | [**\[ 📡 代码仓库 \]**](https://blog.csdn.net/fengtinghuqu520/article/details/147275999?spm=1001.2014.3001.5502) | --------------------------------------- Running Process: 100% \| Latency: 0ms *** ** * ** *** #### 索引与导读 * [友元函数](#友元函数) * * [友元函数的出现缘由](#友元函数的出现缘由) * [友元函数的基本定义](#友元函数的基本定义) * * [1)friend 关键字](#1)friend 关键字) * [2)函数返回类型 (returnType)](#2)函数返回类型 (returnType)) * [3)函数名 (functionName)](#3)函数名 (functionName)) * [4)参数列表 (parameters)](#4)参数列表 (parameters)) * * [4.1)传值](#4.1)传值) * [4.2)传引用](#4.2)传引用) * [4.3)传常量引用](#4.3)传常量引用) * [4.4)传指针](#4.4)传指针) * [4.5)多个参数](#4.5)多个参数) * [4.6)带默认参数](#4.6)带默认参数) * [友元函数的特点](#友元函数的特点) * [友元类](#友元类) * * [1)基本定义](#1)基本定义) * [2)友元关系(友元类)的特性](#2)友元关系(友元类)的特性) * [💻结尾--- 核心连接协议](#💻结尾— 核心连接协议) ## 友元函数 ### 友元函数的出现缘由 * `C++`的封装性将数据隐藏在类内部,但有时外部函数需要直接访问类的私有成员 🚩友元函数解决了这一矛盾 * 当外部函数需要频繁访问类的私有数据时,通过公有接口(`getter/setter`)会产生函数调用开销,友元函数可以直接访问,效率更高 * 某些操作符(如`<<`、`>>`)必须作为非成员函数重载,但又需要访问私有成员 * 当两个或多个类需要共享数据,但这些类之间没有继承关系时,友元函数可以作为桥梁 *** ** * ** *** ### 友元函数的基本定义 ```cpp class ClassName { private: // 私有成员 public: // 声明友元函数 friend returnType functionName(parameters); }; ``` #### 1)friend 关键字 **╔═█▓▒░ CODE CORE 🔥** **┌─────────────┐ │ `friend`关键字 │`friend returnType functionName(parameters);` └─────────────┘** * `friend` 是一个关键字,表示后面声明的是友元函数 * 只在**类内部声明时**使用,在函数定义时不需要 * 友元关系是授予的,不是索取来的 #### 2)函数返回类型 (returnType) ```cpp friend void functionName(); // 无返回值 friend int functionName(); // 返回int friend MyClass functionName(); // 返回自定义类型 friend const string& functionName(); // 返回常量引用 friend auto functionName(); // C++14起可用auto ``` #### 3)函数名 (functionName) ```cpp // 可以是普通函数 friend void printData(const ClassName& obj); // 可以是操作符函数 friend ostream& operator<<(ostream& os, const ClassName& obj); // 可以是模板函数 template friend void templateFunc(T value); ``` *** ** * ** *** #### 4)参数列表 (parameters) ##### 4.1)传值 ```cpp friend void func(ClassName obj); // 传值 ``` * **典例** ```cpp friend void testStatus(Light light) { light.brightness = 100; // 仅修改副本,原灯亮度不变 } ``` ##### 4.2)传引用 **用途:** 直接修改原始对象 ```cpp friend void func(ClassName& obj); // 传引用 ``` * **典例** ```cpp friend void turnOn(Light& light) { light.isOn = true; // 直接改变原始灯的状态 } ``` ##### 4.3)传常量引用 **用途:** 高效读取。不产生拷贝(省内存),且保证函数内部不会意外修改数据 ```cpp friend void func(const ClassName& obj);// 传常量引用 ``` * **典例** ```cpp friend void printInfo(const Light& light) { // 只能读取,尝试修改 light.isOn 会报错 cout << "亮度: " << light.brightness << endl; } ``` ##### 4.4)传指针 **用途:** 处理"可选"对象,可以传递 `nullptr` 表示没有设备 ```cpp friend void func(ClassName* obj); ``` * **典例** ```cpp friend void repair(Light* light) { if (light) { // 检查指针是否为空 light->isBroken = false; } } ``` ##### 4.5)多个参数 **用途:** 处理两个类之间的交互 ```cpp friend void connect(ClassA& a, ClassB& b); ``` * **典例** ```cpp // 在 Remote 和 Light 类中分别声明为友元 friend void pairDevice(Remote& r, Light& l) { r.deviceID = l.id; // 遥控器获取灯的私有 ID l.isPaired = true; // 灯标记为已配对 } ``` ##### 4.6)带默认参数 **用途:** 增加函数的灵活性,提供一种"常用模式",同时允许特殊配置 ```cpp friend void process(ClassName& obj, int mode = 0); ``` * **典例** ```cpp friend void reset(Light& light, int level = 0) { light.brightness = level; // 默认调为0,也可以指定亮度 } ``` *** ** * ** *** ### 友元函数的特点 * **突破封装:** 允许外部访问私有成员。 * **声明方式:** 使用 `friend` 关键字,在类内部声明。 * **非成员函数:** 它是定义在类外部的普通函数,不属于该类,因此没有 `this` 指针。 * **位置随意:** 可以在类定义的任何地方声明 (`public`/`private` 区域均可)。 * **一个函数可以是多个类的友元** ```cpp #include using namespace std; class ClassB; // 【补充】:前向声明,告诉编译器 ClassB 稍后会定义 class ClassA { private: int numA; public: ClassA(int n) : numA(n) {} // 声明 friendFunction 是本类的友元 friend int add(const ClassA& a, const ClassB& b); }; class ClassB { private: int numB; public: ClassB(int n) : numB(n) {} // 声明同一个函数 add 也是本类的友元 friend int add(const ClassA& a, const ClassB& b); }; // 这个函数同时拥有访问 ClassA 和 ClassB 私有成员的权限 int add(const ClassA& a, const ClassB& b) { return a.numA + b.numB; } int main() { ClassA a(10); ClassB b(20); cout << "两类私有成员之和: " << add(a, b) << endl; return 0; } ``` *** ** * ** *** ## 友元类 **友元类(Friend Class)** 是 `C++` 中的一种特殊机制,允许一个类访问另一个类的 **私有(private)** 和 **保护(protected)** 成员 ### 1)基本定义 如果一个**类 A** 将另一个**类 B** 声明为友元,那么 B 的所有成员函数都可以直接访问 A 的私有和保护成员,就好像这些成员在 B 中是公有的一样 ```cpp class A { private: int private_data; // 声明 B 是 A 的友元类 friend class B; }; class B { public: void func(A& obj) { obj.private_data = 10; // 允许访问,因为 B 是 A 的友元 } }; ``` *** ** * ** *** ### 2)友元关系(友元类)的特性 * **单向性**:如果 A 是 B 的友元,这并不意味着 B 也是 A 的友元 * **不可传递**:如果 A 是 B 的友元,且 B 是 C 的友元,这并不意味着 A 是 C 的友元 ```cpp class A { friend class B; // B 是 A 的朋友,B 可以访问 A private: int dataA; }; class B { friend class C; // C 是 B 的朋友,C 可以访问 B private: int dataB; public: void accessA(A& a) { // 正确:因为 B 是 A 的友元 a.dataA = 10; } }; class C { public: void accessB(B& b) { // 正确:因为 C 是 B 的友元 b.dataB = 20; } // void accessA(A& a) { // 【错误】:不可传递! // 虽然 C -> B,B -> A,但 C 不能直接访问 A // a.dataA = 30; // 编译报错 // } }; // 同时也说明了单向性:A 并没有声明 B 是朋友,所以 A 不能访问 B 的私有成员。 ``` *** ** * ** *** ## 💻结尾--- 核心连接协议 **警告:** 🌠🌠正在接入底层技术矩阵。如果你已成功破解学习中的逻辑断层,请执行以下指令序列以同步数据:🌠🌠 *** ** * ** *** **【📡】 建立深度链接:** **关注**本终端。在赛博丛林中深耕底层架构,从原始代码到进阶协议,同步见证每一次系统升级。 **【⚡】 能量过载分发:** 执行**点赞**操作。通过高带宽分发,让优质模组在信息流中高亮显示,赋予知识跨维度的传播力。 **【💾】 离线缓存核心:** 将本页加入**收藏**。把这些高频实战逻辑存入你的离线存储器,在遭遇系统崩溃或需要离线检索时,实现瞬时读取。 **【💬】 协议加密解密:** 在**评论区**留下你的散列码。分享你曾遭遇的代码冲突或系统漏洞(那些年踩过的坑),通过交互式编译共同绕过技术陷阱。 **【🛰️】 信号频率投票:** 通过**投票**发射你的选择。你的每一次点击都在重新定义矩阵的进化方向,决定下一个被全量拆解的技术节点。 *** ** * ** *** ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/57b03915c54b43a7a03fa92dbbfe57c3.gif) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0905dc972de8414bb602715de3f866ee.gif)

相关推荐
晓13132 小时前
第四章:Redis实战应用及常见问题(下篇)
java·数据库·缓存·wpf
小程同学>o<2 小时前
嵌入式之C/C++(一)关键字
c语言·开发语言·c++·嵌入式软件面试
diediedei2 小时前
C++构建缓存加速
开发语言·c++·算法
晚霞的不甘2 小时前
Flutter for OpenHarmony 电商 App 搜索功能深度解析:从点击到反馈的完整实现
开发语言·前端·javascript·flutter·前端框架
没有bug.的程序员2 小时前
Spring Cloud Stream:消息驱动微服务的实战与 Kafka 集成终极指南
java·微服务·架构·kafka·stream·springcloud·消息驱动
{Hello World}2 小时前
Java内部类:深入解析四大类型与应用
java·开发语言
春日见2 小时前
C++单例模式 (Singleton Pattern)
java·运维·开发语言·驱动开发·算法·docker·单例模式
Remember_9932 小时前
网络原理初识:从基础概念到协议分层
开发语言·网络·php
SamRol2 小时前
达梦数据库指令 及 在Spring Boot + MyBatis-Plus上的使用
java·数据库·spring boot·mybatis·达梦·intellij idea