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

大话C++:第15篇 友元

友元(Friend)是C++中的一个特殊概念,它允许一个类或函数访问另一个类的私有和保护成员。友元可以是一个函数,也可以是一个类。

1 友元函数

友元函数(Friend Function)是C++中的一个特殊概念,它允许一个非成员函数访问类的私有(private)和受保护(protected)成员。友元函数不是类的成员函数,但它们被授权可以像类的成员函数一样访问类的私有和保护成员。通常,只有类的成员函数和友元函数能够访问类的私有和保护成员。

在C++中,友元函数的声明语法格式通常是在类的定义中,使用friend关键字后跟函数的声明。

#include <iostream>class Person 
{
public:Person(int age) : _age(age) {}// 声明一个友元函数friend void DisplayPrivateInfo(Person& obj);private:// 私有成员变量int _age;    
};// 定义友元函数
void DisplayPrivateInfo(Person& obj) 
{// 尽管_age是私有的,友元函数仍然可以访问它std::cout << "对象的年龄: " << obj._age << std::endl;
}int main() 
{Person jack(42);// 输出jack的年龄DisplayPrivateInfo(jack);return 0;
}

注意

  • 友元函数可以定义在类的外部,也可以在类的内部定义,但通常的做法是在类的外部定义友元函数,以保持类的定义更加清晰。

  • 友元函数破坏了类的封装性,因此在设计类时应谨慎使用友元函数,只有在确实需要时才应使用。通常,更好的做法是通过类的公有成员函数来访问和修改私有成员,以保持类的封装性和隐藏性。

2 友元类

当一个类被声明为另一个类的友元时,这个类的所有成员函数都可以访问另一个类的私有(private)和受保护(protected)成员。这种关系被称为“友元类”(Friend Class)。

友元类的声明语法格式

class ClassA 
{// ... 类A的成员 ...// 声明ClassB为ClassA的友元类friend class ClassB;
};class ClassB 
{// ... 类B的成员 ...// ClassB的成员函数可以访问ClassA的私有和受保护成员void AccessClassAMembers(ClassA& a) {// 可以直接访问ClassA的私有和受保护成员std::cout << a.privateMemberOfA << std::endl;a.protectedMemberOfA = 42;}
};

其中,ClassB被声明为ClassA的友元类。因此,ClassB中的所有成员函数都可以访问ClassA的私有和受保护成员。需要注意的是,友元关系不是相互的,即使ClassBClassA的友元类,ClassA也不一定是ClassB的友元类,除非在ClassA中也进行了相应的友元类声明。

#include <iostream>// 声明ClassB为ClassA的友元类
class ClassA
{friend class ClassB; // ClassB被声明为ClassA的友元类private:// 私有成员变量int privateVar;public:// 构造函数ClassA(int value) : privateVar(value) {}// 公有成员函数void SetPrivateVar(int value) {privateVar = value;}// 获取私有成员变量的值(通常应该避免这样做,但为了示例而包含)int GetPrivateVar() const {return privateVar;}
};// ClassB,它是ClassA的友元类
class ClassB 
{
public:// ClassB的成员函数可以直接访问ClassA的私有成员void AccessAndModifyClassA(ClassA& a) {// 直接访问并修改ClassA的私有成员std::cout << "修改前,privateVar: " << a.GetPrivateVar() << std::endl;a.privateVar = 42; // 直接修改私有成员std::cout << "修改后,privateVar: " << a.GetPrivateVar() << std::endl;}
};int main() 
{// 创建ClassA的对象ClassA a(10);// 创建ClassB的对象ClassB b;// 使用ClassB的对象来访问和修改ClassA的私有成员b.AccessAndModifyClassA(a);return 0;
}

注意,友元类破坏了类的封装性和隐藏性,因此应该谨慎使用。它们通常只在确实需要访问另一个类的私有成员时才被声明为友元类。在大多数情况下,更好的做法是通过类的公有成员函数来访问和修改私有成员,以保持类的封装性和隐藏性。

3 友元注意事项

由于友元可以突破类的封装性和隐藏性,因此在使用时需要特别注意以下几点:

  • 非对称性:友元关系不是对称的。如果类B是类A的友元,并不意味着类A自动成为类B的友元。需要在类A中也声明类B为友元,才能建立对称的友元关系。

  • 非传递性:友元关系不具有传递性。如果类B是类A的友元,类C是类B的友元,并不意味着类C自动成为类A的友元。需要在类A中明确声明类C为友元,才能建立类C和类A之间的友元关系。

  • 谨慎使用:由于友元可以访问类的私有成员,这破坏了类的封装性和隐藏性。因此,应该谨慎使用友元,只有在确实需要时才应声明友元。通常,更好的做法是通过类的公有成员函数来访问和修改私有成员。

  • 避免过度使用:过度使用友元可能导致代码难以理解和维护。如果一个类有许多友元类或函数,那么它的封装性可能已经被破坏,这可能会导致潜在的安全风险和维护问题。

  • 明确声明:友元关系需要在类定义中明确声明。不论是友元函数还是友元类,都需要在相应的类中使用friend关键字进行声明。

  • 注意命名冲突:由于友元函数或类不是类的成员,它们可能与其他全局函数或类产生命名冲突。因此,在命名友元函数或类时,应该选择具有描述性和唯一性的名称,以避免潜在的命名冲突。

  • 考虑替代方案:在决定使用友元之前,应该考虑是否有其他替代方案可以实现相同的功能,同时保持类的封装性和隐藏性。例如,可以考虑使用公有成员函数和参数来访问和修改私有成员


http://www.mrgr.cn/news/45985.html

相关文章:

  • 如何使用Python连接和操作MySQL数据库?请提供示例代码。
  • 产品推介——施密特触发器光耦KLH11LX产品系列
  • 007集—— 自动获取图形的外边界(外轮廓)(CAD—C#二次开发入门)
  • 【AUTOSAR 基础软件】PduR模块详解(通信路由)
  • 小巧简单的JAVA字节码开源编辑器
  • 工业物联网关-功能概述
  • mount 挂载用法
  • ML 系列:机器学习和深度学习的深层次总结(14) — 逻辑回归(第 3 部分 — 实施)
  • 「软件设计哲学」于延保代码改造中的实践
  • Istio Pilot xDS Sidecar
  • tauri开发Mac电脑Safari浏览器一个很奇怪的问题:在 input 输入框输入的是全小写英文字母,会自动将首字母转换为大写解决办法
  • 离职后才知道的那些事儿
  • MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
  • stateflow一些数据依赖关系的使用
  • Ubuntu下v4l2采集摄像头视频
  • 项目开发--大模型--个人问答知识库--chain控制
  • en造数据结构与算法C# 之 动态规划
  • Nodejs连接Mysql笔记
  • springboot 整合 rabbitMQ(1)
  • 滚雪球学Redis[4.1讲]:Redis的高可用性与集群架构