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

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++编译器在寻找运算符函数时,找的自己内部的函数,有就用显示实现的函数,没有的话就使用默认实现的,有元函数是外部函数,就不太编译器寻找范围内

学习记录,侵权联系删除。
来源:朱老师物联网大课堂

http://www.lryc.cn/news/403465.html

相关文章:

  • 【整理了一些关于使用swoole使用的解决方案】
  • python selenium4 EdgeDriver动态页面爬取
  • 【一次记一句:SQL】从 information_schema.TABLES中查询数据库表中记录数据量
  • NXP i.MX8系列平台开发讲解 - 3.19 Linux TTY子系统(二)
  • FPGA资源容量
  • Zabbix介绍和架构
  • 打造智慧图书馆:AI视频技术助力图书馆安全与秩序管理
  • Go的数据结构与实现【LinkedList】
  • Ubuntu22.04安装CUDA+CUDNN+Conda+PyTorch
  • 当“广撒网”遇上“精准定点”的鱼叉式网络钓鱼
  • svn ldap认证临时切换到本地认证
  • 极狐GitLab如何配置使用独立数据库?
  • TCP状态转换详解
  • SimMIM:一个类BERT的计算机视觉的预训练框架
  • 数据精度丢失
  • Element UI DatePicker选择日期范围区间默认显示前一个月和本月
  • C++:聚合类、嵌套类、局部类、union类详细介绍与分析
  • MKS流量计软件MFC通讯驱动使用于C和P系列MFC控制USB接口W10系统
  • C++:左值/右值引用、移动语义/std::move、万能引用/完美转发std::forward 详解
  • 蜂窝物联云平台:一站式服务,智能生活从此开始!
  • 【中项】系统集成项目管理工程师-第3章 信息技术服务-3.3服务生命周期
  • 【iOS】——消息传递底层实现
  • PostgreSQL数据库从入门到精通系列之十:表空间、索引表空间、创建表空间、创建索引空间、创建分区表、创建分区表的分区、创建指定表空间、索引表空间的分区表
  • 恶补,先验分布,后验分布 ,似然估计
  • JS之数组中的reduce方法
  • 在win10上通过WSL和docker安装Ubuntu子系统,并配置Ubuntu可成功使用宿主机GPU
  • python需要掌握那些语法
  • CentOS Mysql8 数据库安装
  • 新手教程---python-函数(新添加)
  • Windows tasklist命令详解,Windows查看进程