友元

本文详细介绍了C++中友元的概念,包括友元函数和友元类,解释了它们如何突破类的封装性来访问私有成员,以及这种特性的优缺点。同时,文章还提供了多种访问类私有成员的方法,如通过类内成员函数和指针,并附有相关链接深入探讨内联函数、宏函数的区别,以及类的默认成员函数等高级话题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

友元分为:友元函数和友元类


友元函数


友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。


1.友元函数可访问类的私有成员,但不是类的成员函数
2.友元函数不能用const修饰
3.友元函数可以在类定义的任何地方声明,不受类访问限定符限制
4.一个函数可以是多个类的友元函数
5.友元函数的调用与普通函数的调用和原理相同(传参数量)


友元类


友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员


友元的优缺点


优点:提高了程序运行效率(功能方法更全)
缺点:破坏了类的封装性和隐藏性


注:

友元关系不能继承
友元关系是单向的,不具有交换性
友元关系不能传递


问:如何访问一个类内的私有成员?


1.友元函数
2.类内成员函数访问私有成员
3.指针(通过计算偏移量)(此处涉及内存对齐)


结构体内存对齐:
https://blog.youkuaiyun.com/Romantic_C/article/details/81224234
内联函数与宏函数的区别:
https://blog.youkuaiyun.com/Romantic_C/article/details/81489479
类的六个默认成员函数、const、static用法:
https://blog.youkuaiyun.com/Romantic_C/article/details/81487133
类对象模型:
https://blog.youkuaiyun.com/Romantic_C/article/details/81480503
引用&指针、传值&传引用&传址的区别:
https://blog.youkuaiyun.com/Romantic_C/article/details/81461338
C++函数重载:
https://blog.youkuaiyun.com/Romantic_C/article/details/81458578

<think>我们正在讨论C++中的友元函数友元概念。根据用户的问题,需要解释这两个概念。 引用中并没有直接关于友元的内容,但我们可以根据C++知识进行解释。 注意:用户要求使用中文回答,并且按照系统级指令格式化数学表达式(如果有的话,但本题可能没有数学表达式,所以主要关注代码格式)。 另外,需要生成相关问题。 步骤: 1. 解释友元函数友元函数是一个非成员函数,但它可以访问的私有(private)和保护(protected)成员。 2. 解释友元:一个可以声明另一个为其友元,这样友元就可以访问该的私有和保护成员。 3. 注意:友元关系是单向的,不具有传递性(即A是B的友元,B是C的友元,并不意味A是C的友元)。 4. 友元破坏了封装性,因此应谨慎使用。 同时,我们将按照要求生成相关问题。 由于用户的问题中要求使用中文,所以整个回答用中文。 代码部分使用代码块格式。 注意:引用标识的使用。由于我们参考了C++的一般知识,但引用中并没有直接相关的内容,因此我们可以不添加引用标识,或者如果引用中的某些内容相关(比如静态成员)可以适当提及,但友元与静态成员无关。因此,我们主要根据知识回答,不强制添加引用标识。 但是,在回答中,我们可以提到友元函数与成员函数的区别(例如,成员函数有this指针,而友元函数没有),这时可以引用[4]中提到的静态成员函数也没有this指针,但注意友元函数不是静态成员函数,它们是非成员函数。因此,我们可以对比说明。 回答结构: 1. 友元函数 2. 友元 3. 注意事项 4. 示例代码 5. 生成相关问题 示例代码将包括一个友元函数和一个友元的例子。</think>### C++ 友元函数友元详解 #### 一、核心概念 友元(friend)是 C++ 中打破封装性的特殊机制,允许**外部函数或访问私有成员**。主要特点: 1. **单向授权**:友元关系不可传递(A 授权 B ≠ B 自动授权 A) 2. **非继承性**:友元关系不被派生继承 3. **精准控制**:可单独声明特定函数/友元 4. **语法形式**:使用 `friend` 关键字声明 #### 二、友元函数 **定义**:非成员函数访问私有数据 ```cpp class BankAccount { private: double balance; // 私有成员 friend void audit(BankAccount&); // 友元声明 }; // 友元函数实现(无需 BankAccount::) void audit(BankAccount& acc) { std::cout << "审计访问余额: " << acc.balance; // 直接访问私有成员 } ``` **典型应用场景**: - 运算符重载(如 `<<` 流操作符) ```cpp friend std::ostream& operator<<(std::ostream& os, const MyClass& obj); ``` #### 三、友元 **定义**:整个访问另一的私有成员 ```cpp class Sensor { private: int rawData; // 私有数据 friend class DataProcessor; // 友元声明 }; class DataProcessor { public: void calibrate(Sensor& s) { s.rawData += 10; // 直接访问 Sensor 的私有成员 } }; ``` **关键限制**: - 友元关系**不对称**:`DataProcessor` 可访问 `Sensor`,反之不成立 - **不继承**:`DataProcessor` 的派生不能访问 `Sensor` 私有成员 #### 四、注意事项与最佳实践 1. **封装破坏**:过度使用会导致代码耦合(建议优先用公有接口) 2. **前置声明**:友元需提前声明 ```cpp class DataProcessor; // 前置声明 class Sensor { friend class DataProcessor; ... }; ``` 3. **模板特化**:友元声明模板中需特殊处理[^2] ```cpp template<typename T> class Box { friend void inspect<T>(Box<T>&); // 模板友元 }; ``` 4. **与静态成员对比**:友元函数无 `this` 指针,静态成员函数有作用域但无 `this` 指针[^4] #### 五、典型错误示例 ```cpp class A { friend class B; int secret; }; class B { public: void leak(A a) { std::cout << a.secret; } // 合法 }; class C : public B { public: void fail(A a) { std::cout << a.secret; // 错误!友元关系不继承 } }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值