C++ :友元类
友元类的概念和使用
(1)将类A声明为B中的friend class后,则A中所有成员函数都成为类B的友元函数了
(2)代码实战:友元类的定义和使用友元类是单向的
(3)友元类是单向的,代码实战验证
互为友元类
(1)2个类可以互为友元类,代码实战验证
(2)互为友元类要注意互相引用的细节规则
(1)友元类其实就是批量制造友元函数
(2)友元类中所有全部成员都成为了友元函数,相当于一次打了很多洞,极大破坏了面向对象
(3)除非确实有必要,否则建议按需定义友元函数,尽量维护面向对象,让代码更安全健壮
#include <iostream>
#include <string>class Country; // Forward declaration of Country// External friend function declaration
void disp_info_external(const Country &ct);class InfoDisplayer {public:// Member function declarationvoid disp_info_member(const Country &ct) const;
};class InfoFriendClass {public:// Member function to display informationvoid display(const Country &ct) const;
};class Country {private:std::string privateName;protected:int protectedPopulation;public:std::string publicCapital;// ConstructorCountry(std::string name, int population, std::string capital): privateName(name),protectedPopulation(population),publicCapital(capital) {}// Friend function declarationfriend void disp_info_external(const Country &ct);// friend void InfoDisplayer::disp_info_member(const Country &ct);//error: no// declaration matches ‘void InfoDisplayer::disp_info_member(const Country&)’friend class InfoFriendClass; // Friend class declaration
};// Definition of the external friend function
void disp_info_external(const Country &ct) {std::cout << "disp_info_external Name: " << ct.privateName << "\n";std::cout << "disp_info_external Population: " << ct.protectedPopulation<< "\n";std::cout << "disp_info_external Capital: " << ct.publicCapital << "\n";
}// Definition of the member friend function
void InfoDisplayer::disp_info_member(const Country &ct) const {// std::cout << "disp_info_member Name: " << ct.privateName << "\n";// error: ‘int Country::protectedPopulation’ is protected within this context// std::cout << "disp_info_member Population: " << ct.protectedPopulation <<// "\n"; std::cout << "disp_info_member Capital: " << ct.publicCapital <<// "\n";
}// Definition of the friend class member function
void InfoFriendClass::display(const Country &ct) const {std::cout << "InfoFriendClass Name: " << ct.privateName << "\n";std::cout << "InfoFriendClass Population: " << ct.protectedPopulation << "\n";std::cout << "InfoFriendClass Capital: " << ct.publicCapital << "\n";
}int test070401() {// Create an object of CountryCountry myCountry("Wonderland", 5000000, "Magic City");// Display information using the external friend functiondisp_info_external(myCountry);// Create an object of InfoDisplayerInfoDisplayer displayer;// Display information using the member friend functiondisplayer.disp_info_member(myCountry);// Create an object of InfoFriendClassInfoFriendClass friendClass;// Display information using the friend class member functionfriendClass.display(myCountry);return 0;
}

#include <iostream>
#include <string>class Vegetable; // Forward declaration of Vegetableclass Fruit {private:std::string name;protected:std::string color;public:// ConstructorFruit(std::string n, std::string c) : name(n), color(c) {}// Friend class declarationfriend class Vegetable;// Definition of the friend functionvoid displayVegetable(const Vegetable &veg);
};class Vegetable {private:std::string name;protected:std::string color;public:// ConstructorVegetable(std::string n, std::string c) : name(n), color(c) {}// Friend class declarationfriend class Fruit;// Member function declarationvoid displayFruit(const Fruit &fruit) const {std::cout << "Vegetable accessing Fruit's name: " << fruit.name << "\n";std::cout << "Vegetable accessing Fruit's color: " << fruit.color << "\n";}
};void Fruit::displayVegetable(const Vegetable &veg) {std::cout << "Fruit accessing Vegetable's name: " << veg.name << "\n";std::cout << "Fruit accessing Vegetable's color: " << veg.color << "\n";
}int test070402() {// Create objects of Fruit and VegetableFruit apple("Apple", "Red");Vegetable spinach("Spinach", "Green");apple.displayVegetable(spinach);// Display information using the member function of Vegetablespinach.displayFruit(apple);return 0;
}

为什么会有友元函数
使用友元函数的优缺点
(1)缺点:破坏了封装机制,尽量不使用友元函数,不得已才使用友元函数
(2)优点:在实现类之间数据共享时,减少系统开销,提高效率。
使用友元函数的两种情况
(1)运算符重载的某些场合需要使用友元
(2)两个类要共享数据的时候
两个类如何共享数据
(1)类内的数据,其实就是类的成员变量
(2)2个类共享数据方法1:将共享数据访问权限设置为public。
(3)2个类共享数据方法2:通过第三个专门封装数据的类,和2个类中带参数的成员函数来传参共享
(4)2个类共享数据方法3:通过友元函数打洞
友元函数和类的成员函数的区别
(1)成员函数有this指针,而友元函数没有this指针。为什么?因为友元只是朋友,并不是类内“自家人”
(2)友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。
(3)友元关系不具有传递性。类B是类A的友元,类C是B的友元,类C不一定是类A的友元,要看类中是否有相应的声明
共有友元函数
(1)1个函数同时成为2个类的友元函数
(2)共有友元函数可以是外部函数,也可以是某个(第3个)类的成员函数
(3)共有友元函数内可同时访问2个类的受保护成员,间接将2个完全无关的类的数据打通了
总结
有元函数是单向的
两个类可以互为有元类、可以相互拥有有元方法
C++编译器在寻找运算符函数时,找的自己内部的函数,有就用显示实现的函数,没有的话就使用默认实现的,有元函数是外部函数,就不太编译器寻找范围内
学习记录,侵权联系删除。
来源:朱老师物联网大课堂
相关文章:
C++ :友元类
友元类的概念和使用 (1)将类A声明为B中的friend class后,则A中所有成员函数都成为类B的友元函数了 (2)代码实战:友元类的定义和使用友元类是单向的 (3)友元类是单向的,代码实战验证 互为友元类 (1)2个类可以互为友元类,代码实战…...
【整理了一些关于使用swoole使用的解决方案】
目录 如何监控和分析 Swoole 服务器的性能瓶颈? 在进行 Swoole 服务器性能优化时,有哪些常见的错误和陷阱需要避免? 除了 Swoole,还有哪些 PHP 框架或技术可以用于构建高并发的 Web 应用? Swoole 同步请求在高并发…...
python selenium4 EdgeDriver动态页面爬取
截止至2024.7.16 chrome浏览器最新版本为126.0.6478.127 但对应的chromeDriver版本都低于此版本,因此,转用Edge浏览器 说明:仅记录自己使用过程中用到的一些代码和感受,看具体情况不定期更新。 selenium官方文档 1、安装selen…...
【一次记一句:SQL】从 information_schema.TABLES中查询数据库表中记录数据量
有时候,一张千万数据量的表,使用 count(*) 统计记录数,查不动。可以使用下述SQL来试试: SELECT CONCAT(table_schema, ., table_name) AS "Table Name", table_rows AS "Number of Rows", CONCAT(ROUND(data…...
NXP i.MX8系列平台开发讲解 - 3.19 Linux TTY子系统(二)
专栏文章目录传送门:返回专栏目录 Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】 目录 1. Linux 串口驱动 1.1 Uart 驱动注册流程 1.2 uart 操作函数 1.3 line discipline 2. Linux tty应用层使用…...
FPGA资源容量
Kintex™ 7 https://www.amd.com/zh-tw/products/adaptive-socs-and-fpgas/fpga/kintex-7.html#product-table AMD Zynq™ 7000 SoC https://www.amd.com/en/products/adaptive-socs-and-fpgas/soc/zynq-7000.html#product-table AMD Zynq™ UltraScale™ RFSoC 第一代 AMD Z…...
Zabbix介绍和架构
目录 一.Zabbix简介 1.为什么需要监控 2.需要监控什么 3.常见的监控工具 4.Zabbix使用场景及系统概述 5.Zabbix 架构 6.Zabbix工作流程 7.Zabbix 术语 二. 部署安装zabbix 三.zabbix 配置文件 一.Zabbix简介 1.为什么需要监控 运维行业有句话:“无监控、不运维”&am…...
打造智慧图书馆:AI视频技术助力图书馆安全与秩序管理
一、背景需求 随着信息技术的飞速发展,图书馆作为重要的知识传播场所,其安全管理也面临着新的挑战。为了确保图书馆内书籍的安全、维护读者的阅读环境以及应对突发事件,TSINGSEE青犀旭帆科技基于EasyCVR视频监控汇聚平台技术与AI视频智能分析…...
Go的数据结构与实现【LinkedList】
介绍 所谓链表(Linked List),就是按线性次序排列的一组数据节点。每个节点都是一个对象,它通过一个引用指向对应的数据元素,同时还通过一个引用next指向下一节点。 实现 逻辑方法 我们定义链表的结构体:…...
Ubuntu22.04安装CUDA+CUDNN+Conda+PyTorch
步骤: 1、安装显卡驱动; 2、安装CUDA; 3、安装CUDNN; 4、安装Conda; 5、安装Pytorch。 一、系统和硬件信息 1、Ubuntu 22.04 2、显卡:4060Ti 二、安装显卡驱动 (已经安装的可以跳过&a…...
当“广撒网”遇上“精准定点”的鱼叉式网络钓鱼
批量网络钓鱼电子邮件活动倾向于针对大量受众,它们通常使用笼统的措辞和简单的格式,其中不乏各种拼写错误。而有针对性的攻击往往需要付出更大的努力,攻击者会伪装成雇主或客户向目标发送包含个人详细信息的个性化消息。在更大范围内采用这种…...
svn ldap认证临时切换到本地认证
当前的svn是在CentOS 7 下 SVN、 Apache 对接 LDAP 服务实现用户账号管理和权限认证,本文模拟ldap数据丢失如何恢复svn,方法是临时将认证切换到本地认证 编辑subversion.conf文件 vi /etc/httpd/conf.d/subversion.conf 注释ldap-status #<Locati…...
极狐GitLab如何配置使用独立数据库?
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab :https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署…...
TCP状态转换详解
1.什么是TCP的状态转换 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议。在 TCP 连接的生命周期中,连接的状态会随着不同阶段的通信而发生变化,这些变化被称为状…...
SimMIM:一个类BERT的计算机视觉的预训练框架
1、前言 呃…好久没有写博客了,主要是最近时间比较少。今天来做一期视频博客的内容。本文主要讲SimMIM,它是一个将计算机视觉(图像)进行自监督训练的框架。 原论文:SimMIM:用于掩码图像建模的简单框架 (a…...
数据精度丢失
js数据精度丢失 最近看面试题想到了之前在开发钟遇到过的问题,现总结一下 在开发过程中,发现从后台返回的数据结构中的id字段在前端显示为不正确的值。经过排查,怀疑是JavaScript中Number类型精度丢失的问题。通过将id字段的类型从Number改为…...
Element UI DatePicker选择日期范围区间默认显示前一个月和本月
要求:点击el-date-picker选择时间范围时,默认展开当月和上个月。 但是Element UI的组件默认展开的是本月和下一个月,如下图所示: 改为 <span click"changeInitCalendarRange"><el-date-picker v-model"r…...
C++:聚合类、嵌套类、局部类、union类详细介绍与分析
聚合类 (1)What(什么是聚合类) 本质是一个自定义类型的数据结构(结构体或类),但聚合类有以下特性: 所有的成员都是public没有任何构造函数没有基类类内部没有初始值 (2)Why(聚合类的作用&…...
MKS流量计软件MFC通讯驱动使用于C和P系列MFC控制USB接口W10系统
MKS流量计软件MFC通讯驱动使用于C和P系列MFC控制USB接口W10系统...
C++:左值/右值引用、移动语义/std::move、万能引用/完美转发std::forward 详解
你能学到 左值 与 右值左值引用 与 右值引用 基本用法与作用拷贝构造函数 与 移动构造函数移动语义 与 std::move万能引用 与 引用折叠完美转发:std::forward 前言 本文代码片段中变量命名规则如下: 小写字母:一般类型的变量(非…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
