
⚡ CYBER_PROFILE ⚡
/// SYSTEM READY ///
WARNING : DETECTING HIGH ENERGY
🌊 🌉 🌊 心手合一 · 水到渠成

|------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| >>> ACCESS TERMINAL <<< ||
| 🦾 作者主页 | 🔥 C语言核心 |
| 💾 编程百度 | 📡 代码仓库 |
Running Process: 100% | Latency: 0ms
索引与导读
- 友元函数
-
- 友元函数的出现缘由
- 友元函数的基本定义
-
- [1)friend 关键字](#1)friend 关键字)
- 2)函数返回类型 (returnType)
- 3)函数名 (functionName)
- 4)参数列表 (parameters)
- 友元函数的特点
- 友元类
- [💻结尾--- 核心连接协议](#💻结尾— 核心连接协议)
友元函数
友元函数的出现缘由
-
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<typename T>
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 <iostream>
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 的私有成员。
💻结尾--- 核心连接协议
警告: 🌠🌠正在接入底层技术矩阵。如果你已成功破解学习中的逻辑断层,请执行以下指令序列以同步数据:🌠🌠
【📡】 建立深度链接: 关注本终端。在赛博丛林中深耕底层架构,从原始代码到进阶协议,同步见证每一次系统升级。
【⚡】 能量过载分发: 执行点赞操作。通过高带宽分发,让优质模组在信息流中高亮显示,赋予知识跨维度的传播力。
【💾】 离线缓存核心: 将本页加入收藏。把这些高频实战逻辑存入你的离线存储器,在遭遇系统崩溃或需要离线检索时,实现瞬时读取。
【💬】 协议加密解密: 在评论区留下你的散列码。分享你曾遭遇的代码冲突或系统漏洞(那些年踩过的坑),通过交互式编译共同绕过技术陷阱。
【🛰️】 信号频率投票: 通过投票发射你的选择。你的每一次点击都在重新定义矩阵的进化方向,决定下一个被全量拆解的技术节点。

