C++类和对象之友元

文章目录

  • 4 类和对象
    • 4.4 友元
      • 4.4.1 全局函数做友元
      • 4.4.2 类做友元
      • 4.4.3 成员函数做友元
      • 4.4.4 Date类作为person类的友元

4 类和对象


4.4 友元


​ 生活中你的家有客厅(Public),有你的卧室(Private)。

​ 客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去。

​ 但是呢,你也可以允许你的好闺蜜好基友进去。

​ 在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术。

​ 友元的目的就是让一个函数或者类 访问另一个类中私有成员。

​ 友元的关键字为 friend

​ 友元的三种实现

  • 全局函数做友元
  • 类做友元
  • 成员函数做友元

4.4.1 全局函数做友元


例4.4.1

#include <iostream>using namespace std;class Building
{//告诉编译器 goodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容friend void goodGay(Building * building);public:Building(){this->m_SittingRoom = "客厅";this->m_BedRoom = "卧室";}public:string m_SittingRoom; //客厅private:string m_BedRoom; //卧室
};void goodGay(Building * building)
{cout << "好基友正在访问: " << building->m_SittingRoom << endl;cout << "好基友正在访问: " << building->m_BedRoom << endl;
}void test01()
{Building b;goodGay(&b);
}int main()
{test01();return 0;
}

​ 结果如下:

好基友正在访问: 客厅
好基友正在访问: 卧室Process returned 0 (0x0)   execution time : 0.032 s
Press any key to continue.

4.4.2 类做友元


例4.4.2

#include <iostream>using namespace std;class Building;class goodGay
{
public:goodGay();void visit();private:Building *building;
};class Building
{//告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容friend class goodGay;public:Building();public:string m_SittingRoom; //客厅
private:string m_BedRoom;//卧室
};Building::Building()
{this->m_SittingRoom = "客厅";this->m_BedRoom = "卧室";
}goodGay::goodGay()
{building = new Building;
}void goodGay::visit()
{cout << "好基友正在访问" << building->m_SittingRoom << endl;cout << "好基友正在访问" << building->m_BedRoom << endl;
}void test01()
{goodGay gg;gg.visit();}int main()
{test01();return 0;
}

​ 结果如下:

好基友正在访问客厅
好基友正在访问卧室Process returned 0 (0x0)   execution time : 0.009 s
Press any key to continue.

4.4.3 成员函数做友元


例4.4.3

#include <iostream>using namespace std;class Building;class goodGay
{
public:goodGay();void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容void visit2();private:Building *building;
};class Building
{//告诉编译器  goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容friend void goodGay::visit();public:Building();public:string m_SittingRoom; //客厅
private:string m_BedRoom;//卧室
};Building::Building()
{this->m_SittingRoom = "客厅";this->m_BedRoom = "卧室";
}goodGay::goodGay()
{building = new Building;
}void goodGay::visit()
{cout << "好基友正在访问" << building->m_SittingRoom << endl;cout << "好基友正在访问" << building->m_BedRoom << endl;
}void goodGay::visit2()
{cout << "好基友正在访问" << building->m_SittingRoom << endl;//cout << "好基友正在访问" << building->m_BedRoom << endl;
}void test01()
{goodGay  gg;gg.visit();}int main()
{test01();return 0;
}

​ 结果如下:

好基友正在访问客厅
好基友正在访问卧室Process returned 0 (0x0)   execution time : 0.013 s
Press any key to continue.

4.4.4 Date类作为person类的友元

​ 题目如下:

​ 上机实验三,沿用上机实验二的Person类,设计一个Date类,并在Person中增加Date的对象Birthday(has a)。将类定义(class definition)写在 Person.h 及 Date.h 中。 将成员函数(member function)写在 person.cpp 及 Date.cpp中。
​ 编程一個主程式(main) 在主程序中建构两个 Person 对象,一个用全预设值,另一个给定所有的参数。 测试所有的功能,打印(print())对象的内容。
Date

<<constructor>>+Date(y : int = 0, m : int = 0,d : int = 0)
<<destructor>>+~Date()
+setYear(y : int) : void
+setMonth(m : int) : void
+setDay(d : int) : void
+getYear() : int
+getMonth() : int
+getDay() : int
+print() : void
-Year : int
-Month : int
-Day : int

Person

-Name : string
-ID : int
-Address : string
-Birthday: Date
<<constructor>> +Person(name : string = “”, id : int =
0, address : string = “”, Date = Date())
<<desctructor>> +~Person()
+setName(name : string)
+getName() : string
+setID(id : int)
+getID() : int
+setAddress(address : string)
+getAddress() : string
+setBirthday(d : Date)
+getBirthday() : Date
+print() : void

​ 解答如下:

​ main.cpp

#include <iostream>
#include "Person.h"
using namespace std;int main()
{Person myPerson;// Person myPerson("S.M.Wang", 070145, "莲花路200号");cout << "请输入姓名:" ;string name;cin >> name;cout << "请输入ID:" ;int id;cin >> id;cout << "请输入住址:" ;string address;cin >> address;Date myDate;cout << "请输入生日年:" ;int year;cin >> year;cout << "请输入生日月:" ;int month;cin >> month;cout << "请输入生日天:" ;int day;cin >> day;myPerson.setName(name);myPerson.setID(id);myPerson.setAddress(address);myDate.setYear(year);myDate.setMonth(month);myDate.setDay(day);myPerson.setBirthday(myDate); // 调用的形参为类myPerson.print();return 0;
}

​ Person.h

#include <iostream>
#include "Date.h"
using namespace std;class Person
{
public:Person();Person(string name, int id, string address);~Person();void setPerson(string name, int id, string address);void setName(string name);void setID(int id);void setAddress(string address);void setBirthday(Date d);string getName();int getID();string getAddress();Date getBirthday();void print(); // outPutResult
private:string Name;int ID;string Address;Date Birthday;
};

​ Date.h

#include <iostream>using namespace std;class Date
{friend class Person;
public:Date();Date(int y, int m, int d);~Date();void setYear(int y);void setMonth(int m);void setDay(int d);int getYear();int getMonth();int getDay();void print();
private:int Year;int Month;int Day;};

​ Person.cpp

#include "Person.h"
#include <iostream>
using namespace std;Person::Person()
{Name = "S.M.Wang";ID = 070145;Address = "莲花路200号";
}Person::Person(string name, int id, string address)
{setPerson(name, id, address);
}Person::~Person()
{//cout << "object Destructor is called" << endl;
}void Person::setPerson(string name, int id, string address)
{Name = name;ID = id;Address = address;
}void Person::setName(string name)
{Name = name;
}void Person::setID(int id)
{ID = id;
}void Person::setAddress(string address)
{Address = address;
}string Person::getName()
{return Name;
}int Person::getID()
{return ID;
}string Person::getAddress()
{return Address;
}void Person::setBirthday(Date d) // 调用的形参是类
{Birthday = d;
}Date Person::getBirthday() // 返回的是类
{return Birthday;
}void Person::print()
{cout << "Name:" << getName() << endl;cout << "ID:" << getID() << endl;cout << "Address:" << getAddress() << endl;cout << "Birthday:" << getBirthday().getYear(); // getBirthday()返回的是类,再调用类中的子函数满足cout的返回值。cout << " " << getBirthday().getMonth();cout << " " << getBirthday().getDay() << endl;
}

​ Date.cpp

#include "Date.h"
#include <iostream>
using namespace std;Date::Date()
{Year = 0;Month = 0;Day = 0;
}Date::Date(int year, int month, int day)
{setYear(year);setMonth(month);setDay(day);
}Date::~Date()
{//cout << "object Destructor is called" << endl;
}void Date::setYear(int year)
{Year = year;
}void Date::setMonth(int month)
{Month = month;
}void Date::setDay(int day)
{Day = day;
}int Date::getYear()
{return Year;
}int Date::getMonth()
{return Month;
}int Date::getDay()
{return Day;
}void Date::print()
{cout << "Year :" << getYear() << endl;cout << "Month :" << getMonth() << endl;cout << "Day :" << getDay() << endl;
}

​ 结果如下:

请输入姓名:S.M.Wang
请输入ID:070145
请输入住址:莲花路200号
请输入生日年:2000
请输入生日月:1
请输入生日天:1
Name:S.M.Wang
ID:70145
Address:莲花路200号
Birthday:2000 1 1Process returned 0 (0x0)   execution time : 49.737 s
Press any key to continue.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453884.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 入门 - 拉取/创建镜像 + 运行和管理容器

写在前面&#xff1a; 本篇简单介绍一下如何入手 Docker&#xff0c;从 创建/拉取 镜像&#xff0c;再到运行和管理容器&#xff0c;还包括导出容器等操作。这里先贴一下官方的文档地址&#xff1a; Docker DocsDocker Documentation is the official Docker library of reso…

在Windows系统中,cmd 查看 MongoDB 相关信息

MongoDB是一种流行的NoSQL数据库&#xff0c;广泛应用于各种现代应用程序中。 1 查看MongoDB的版本号 要查看MongoDB的版本号&#xff0c;可以使用mongo命令连接到MongoDB&#xff0c;然后执行db.version()。 mongo连接到数据库后&#xff0c;执行以下命令&#xff0c;输出M…

java如何部署web后端服务

java如何部署web后端服务 简单记录一下&#xff0c;方便后续使用。 部署流程 1.web打包 2.关掉需要升级的运行中的服务 /microservice/hedgingcustomer-0.0.1-SNAPSHOT/conf/bin/ 执行脚本 sh shutdown.sh 3.解压文件 返回到/microservice 将升级包上传到该路径&#x…

10款超好用的文档加密软件|2024企业常用文档加密软件排行榜!

在当今的数字化时代&#xff0c;企业的数据安全已经成为了一项至关重要的任务。为了确保企业核心信息资产的安全性和完整性&#xff0c;越来越多的企业开始采用文档加密软件。以下是2024年企业常用的10款超好用的文档加密软件排行榜。 1. Ping32文档加密软件 Ping32是一款功能…

重磅发布,Wireshark 4.4.1 修复多个漏洞,性能新升级

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 中午好&#xff0c;我的网工朋友 Wireshark 一直以其强大的数据包捕获和分析功能而闻名。作为网络工程师、安全分析师和开发者的重要工具&#x…

Java项目-基于spingboot框架的校友社交系统系统项目实战(附源码+文档)

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

中石化万总经理一行莅临点赋科技公司考察调研

近日&#xff0c;中石化万总经理一行莅临点赋科技公司&#xff0c;进行了坦诚而富有成效的交流&#xff0c;双方在轻松而又热烈的氛围中&#xff0c;逐步达成了初步合作意向。 在参观过程中&#xff0c;点赋科技董事长崔梦姣详细介绍了公司的发展历程、核心技术以及未来的发展规…

IDEA下lombok安装及找不到get,set的问题的解决方法

在IDEA中使用Lombok,但是在编译时&#xff0c;提示找不到set()和get()方法&#xff0c;明明在javabean中使用了Data注解&#xff0c;但是编译器就是找不到。 Idea下安装Lombok(需要二步) 第一步&#xff1a; pom.xml中加入lombok依赖包 1 2 3 4 5 6 7 <!-- https://mvnre…

【真题笔记】09-12年系统架构设计师要点总结

【真题笔记】09-12年系统架构设计师要点总结 41 视图DSSA&#xff08;特定领域架构&#xff09;集成系统数据库管理设计模式操作符运算符综合布线备份数据库集成工作流技术软件质量保证需求管理需求开发结构化方法企业战略数据模型事务数据库主题数据库系统设计原型开发静态分析…

SAP B1 账套锁定解决方案

背景 忘记账套密码时&#xff0c;随着尝试密码失败的次数变多&#xff0c;可能会出现账套锁定并报错的情况&#xff0c;如下图&#xff1a; 本文给出一个解决方案&#xff0c;供参考。 解决方案 效果&#xff1a;无法直接找回密码&#xff0c;或重置密码&#xff0c;但是可以…

代码随想录-环形链表II

题目与解析 题目链接:环形链表II 本题两个关键点&#xff0c;1、确定有环 2、确定环的入口位置 提供两种解法&#xff0c;第一种是我借助了一个辅助的列表来记录指针&#xff0c;空间复杂度O(n)比较无脑 第二种是Carl哥的双指针法&#xff0c;又是套圈问题&#xff0c;…

「毅硕|生信教程」 micromamba:mamba的C++实现,超越conda

1 Micromamba 简介 大家是否有这样的经历&#xff0c;使用conda/anaconda进行环境配置的是否速度非常慢&#xff0c;进度经常卡在“Collecting package metadata”上。甚至有时候需要安装的软件比较多&#xff0c;或者需要用到conda-forge这个最大的channel&#xff0c;conda能…

Windows环境下Qt Creator调试模式下qDebug输出中文乱码问题

尝试修改系统的区域设置的方法&#xff1a; 可以修复问题。但会出现其它问题&#xff1a; 比如某些软件打不开&#xff0c;或者一些软件界面的中文显示乱码&#xff01; 暂时没有找到其它更好的办法。

渗透基础-rcube_webmail版本探测

简介 本文介绍了开源产品RoundCube webmail邮件系统的版本探测思路&#xff0c;并用go语言实现工具化、自动化探测。 正文 0x01 探测思路研究 探测系统版本&#xff0c;最理想的方法就是系统主页html代码中有特定的字符串&#xff0c;比如特定版本对应的hash在主页的html代…

【开源免费】基于SpringBoot+Vue.JS母婴商城系统 (JAVA毕业设计)

本文项目编号 T 030 &#xff0c;文末自助获取源码 \color{red}{T030&#xff0c;文末自助获取源码} T030&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

OpenCV高级图形用户界面(11)检查是否有键盘事件发生而不阻塞当前线程函数pollKey()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 轮询已按下的键。 函数 pollKey 无等待地轮询键盘事件。它返回已按下的键的代码或如果没有键自上次调用以来被按下则返回 -1。若要等待按键被按…

【Ansiable】ansible的模块和主机清单

目录 一、介绍一些运维自动化工具 二、Ansible 概述/简介 三、Ansible 工作机制 3.1 内部工作机制 3.2 外部工作机制 四、Ansible 执行流程 五、Ansblie 安装以及日常操作模块***** 5.1 ansible 环境安装部署 5.2 ansible 命令行模块 5.2.1 command 模块 5.2.2 shel…

大数据-177 Elasticsearch Query DSL - 聚合分析 指标聚合 桶聚合

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

VSCode设置用鼠标滚轮控制字体大小

VSCode设置用鼠标滚轮控制字体大小 1. 在左下角&#xff0c;打开设置选项&#xff1a; 2. 找到字体设置&#xff0c;直接修改配置文件&#xff1a; 3. 在配置文件中添加如下内容&#xff1a; "editor.mouseWheelZoom": true别忘了上一行要以逗号结尾。 4. 按住ctrl…

西圣、酷盟和绿联哪款平替电容笔好?三款电容笔真实测评对比

随着越来越多的人开始体验无纸化学习和办公&#xff0c;电容笔成为了一个广受欢迎的iPad配件。而原装电容笔价格太高&#xff0c;如果能有性能相当&#xff0c;价格低廉的替代品&#xff0c;无疑会减轻一些经济负担。因此&#xff0c;平替电容笔应运而生&#xff0c;成为了许多…