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

【C++】友元friend的含义和用法

friend 的含义

在 C++ 中,friend 关键字用于声明某个函数或类为当前类的友元(friend)。友元可以访问类的私有成员(private)受保护成员(protected),即使这些成员对于普通的非友元类或函数是不可见的。

语法
  • 声明一个函数为友元:
    class MyClass {
        friend void MyFriendFunction(); // 函数是 MyClass 的友元
    };
    
  • 声明另一个类为友元:
    class MyClass {
        friend class AnotherClass; // AnotherClass 是 MyClass 的友元
    };
    

friend 的作用

class CMonitor
{
    friend CMonitorTimer;
};

这里声明了 CMonitorTimerCMonitor 类的友元。这意味着:

  • CMonitorTimer可以直接访问 CMonitor 的所有成员,包括私有成员和受保护成员。
  • 这种访问不受 publicprotectedprivate 限制。

这样写的好处

这种设计通常是为了在两个类之间实现更紧密的协作,同时保留必要的封装。以下是其优点:

1. 实现更紧密的关联
  • CMonitorTimer 是专门为 CMonitor 服务的辅助类。
  • 通过友元关系,CMonitorTimer 可以直接访问 CMonitor 的私有或受保护成员,而无需通过公共接口,避免了额外的开销或复杂性。
2. 保留封装性
  • 使用友元时,CMonitor 的私有成员仍然对其他类保持不可见。
  • 不必为了让 CMonitorTimer 访问这些私有成员而将其提升为 public,从而保证了封装性。
3. 简化代码
  • 如果没有 friend 关系,为了实现类似的功能,可能需要提供大量的 publicprotected 的 getter 和 setter 函数,增加了代码复杂性。
  • 通过友元,可以直接在 CMonitorTimer 中访问 CMonitor 的私有成员,简化代码逻辑。

实践

CMonitor 类和一个辅助计时器类 CMonitorTimer

#include <iostream>
using namespace std;

class CMonitor {
private:
    int data; // 私有数据成员

public:
    CMonitor(int val) : data(val) {}
    void Display() const {
        cout << "CMonitor Data: " << data << endl;
    }

    friend class CMonitorTimer; // 声明友元类
};

class CMonitorTimer {
public:
    void ModifyMonitor(CMonitor& monitor) {
        // 直接访问 CMonitor 的私有成员
        monitor.data += 10;
    }
};

int main() {
    CMonitor monitor(5);
    monitor.Display();

    CMonitorTimer timer;
    timer.ModifyMonitor(monitor); // 修改私有成员
    monitor.Display();

    return 0;
}
输出:
CMonitor Data: 5
CMonitor Data: 15

注意事项

1. 滥用友元破坏封装性
  • 友元打破了类的封装性,因此不要轻易滥用友元。
  • 友元关系应该仅用于两个高度相关、需要紧密协作的类或函数。
2. 难以维护
  • 如果友元关系使用过多,类之间的耦合度可能会增加,代码的维护性会降低。
  • 尽量保持友元的使用简单、明确,避免复杂的依赖链。
3. 调试和阅读代码时需要额外注意
  • 友元允许类直接操作另一个类的私有成员,代码逻辑可能会隐晦,给调试和理解代码带来额外负担。


http://www.kler.cn/a/406812.html

相关文章:

  • n、nvm、nrm、pnpm、yarn各种指令大全
  • NUXT3学习日记四(路由中间件、导航守卫)
  • VSCode快速生成vue组件模版
  • 计算机网络socket编程(4)_TCP socket API 详解
  • 华为机试HJ60 查找组成一个偶数最接近的两个素数
  • JavaWeb之综合案例
  • Java项目实战II基于SpringBoot的共享单车管理系统开发文档+数据库+源码)
  • pve 磁盘选错位置修改
  • MySQL系列之远程管理(安全)
  • 鸿蒙进阶-状态管理
  • 力扣-位运算-1【算法学习day.41】
  • 《深入浅出HTTPS​​​​​​​​​》读书笔记(9):对称加密算法
  • 第三十二篇 MobileNetV3论文翻译:《搜索 MobileNetV3》
  • React核心功能详解(一)
  • Debezium系列之:Debezium3版本源码阅读理解
  • Webpack之后,Rollup如何引领前端打包新潮流?(1)
  • SQLite Having 子句
  • C语言程序编译和链接
  • 利用 GitHub 和 Hexo 搭建个人博客【保姆教程】
  • seq2seq attention详解
  • 用nextjs开发时遇到的问题
  • 安卓应用安装过程学习
  • 苹果Siri将搭载大型语言模型,近屿智能抢占AIGC大模型人才培养高地
  • 掌握Go语言中的异常控制:panic、recover和defer的深度解析
  • 嵌入式Linux学习——标准 I/O 库
  • 【前端知识】前端组件-axios详细介绍