10. 类的友元

news2024/9/21 14:53:16

一、类的友元

生活中你的家有客厅(public),有你的卧室(private),客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是,你也可以允许你的好闺蜜好基友进去

  • 友元关系:一个类主动声明哪些其他函数或者是它的朋友,进而给它们提供对本类的访问特许

    • 一些类中的私有属性想让类外的一些特殊的函数或者其他类进行访问
  • 一种数据共享机制

    • 不同类或对象的成员函数之间
    • 类的成员函数与一般函数之间
  • 友元是C++提供的一种破坏数据封装和数据隐藏的机制,为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元

二、友元函数

  • 在类中用关键字friend修饰的非成员函数
    • 友元函数不是类的内部成员函数,而是一个类外的函数
    • 在友元函数体内可以通过对像名访问类中的private和protected成员
  • 在类中声明友元函数原型,在类外定义该友元函数
  • 作用:
    • 增加灵活性,可以在封装和快速性方面做合理选择

示例:

  • 建筑物类中,客厅是公有成员,可在类外进行访问,卧室是私有成员,在类外不可访问到

  • 在test01中调用建筑物类,访问卧室会报错

  • 完整程序:存在错误,类外无法访问私有成员

// 建筑物类
class Building {
public:
	// 构造函数
	Building() {
		m_SittingRoom = "客厅";
		m_BedRoom = "卧室";		
	}
public:
	string m_SittingRoom;	// 客厅,公共属性
private:
	string m_BedRoom;		// 卧室,私有属性
};

// 全局函数
// 要求能够访问Building类中的公共和私有成员
void goodGay(Building *building) {
	cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;  // 公共属性
	cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;		// 私有属性
}

void test01() {
	Building building;
	goodGay(&building);
}

int main() {
	test01();
}
image-20220608102403432
  • 解决方法:定义友元
image-20230510110543903
# include <iostream>
# include <string>
using namespace std;
// 建筑物类
class Building {
	friend void goodGay(Building* building);
public:
	// 构造函数
	Building() {
		m_SittingRoom = "客厅";
		m_BedRoom = "卧室";		
	}
public:
	string m_SittingRoom;	// 客厅
private:
	string m_BedRoom;		// 卧室
};

// 全局函数
// 要求能够访问Building类中的公共和私有成员
void goodGay(Building *building) {
	cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
	cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;
}

void test01() {
	Building building;
	goodGay(&building);
}

int main() {
	test01();
}

示例:计算两个点之间的距离

#include <iostream>
#include <cmath>

class Point {
private:
    int x, y;
public:
    Point(int x = 0, int y = 0) {
        this->x = x;
        this->y = y;
    }
    int getX(){ return x; }
    int getY(){ return y; }
    
    friend double dist(Point &a, Point &b);	// 类内声明友元函数原型
}

// 类外定义友元函数dist()
// 传入两个Point类对象
double dist(Point& a, Point& b) {
    double x = a.x - b.x;
    double y = a.y - b.y;
    return (sqrt(x*x + y*y));
}

int main(){
    Point p1(1, 1), p2(4, 5);
    cout << "The distance is: ";
    cout << dist(p1, p2) << endl;
    return 0;
}

/************* 不用友元 ***********/
class Point {
private:
    int x, y;
public:
    Point(int x = 0, int y = 0) {
        this->x = x;
        this->y = y;
    }
    int getX(){ return x; }
    int getY(){ return y; }
}
double dist(Point& a, Point& b) {
    double x = a.getX() - b.getX(); // 类Point提供了getX()函数才可以这样
    double y = a.getY() - b.getY();
    return (sqrt(x*x + y*y));
}

三、友元类

  • 一个类可以将另一个类声明为友元类
    • 若A类为B类的友元类,则A类的所有成员函数都是B类的友元函数,都可以访问B类的私有和保护成员
  • 注意:
    • 友元关系不能传递
    • 友元关系是单向的
    • 友元关系不被继承

示例:

  1. 将一个类定义为另一个类的友元

将GoodGay类定义为Building类的友元,使GoodGay类可以访问Building类的私有成员

# include <iostream>
# include <string>
using namespace std;

class Building;		// 类声明

class GoodGay {
public:
	// 构造函数
	GoodGay();
	void visit();			// 参观函数,访问Building中的属性
	Building* building;
};

class Building {
	// GoodGay类是本类中的好朋友,可以访问本类中的私有成员
	friend class GoodGay;
public:
	// 构造函数
	Building();
public:
	string m_SittingRoom;	// 客厅
private:
	string m_BedRoom;		// 卧室
};

//类外写成员函数(构造函数)
Building::Building() {
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";
}
GoodGay::GoodGay() {
	//创建建筑物对象
	building = new Building;
}

// 参观函数,访问Building中的属性
void GoodGay::visit() {
	cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
	cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;
}

void test01() {
	GoodGay gg;
	gg.visit();
}

int main() {
	test01();
}
  1. 将一个类的成员函数定义为另一个类的友元

GoodGay类中的visit函数定义为Building类的友元,使visit可以访问Building类的私有成员

GoodGay类中的visit2()函数不可访问Building类的私有成员

# include <iostream>
# include <string>
using namespace std;

class Building;		// 类声明
class GoodGay {
public:
	// 构造函数
	GoodGay();
	void visit();			// 让visit函数可以访问Building中的私有成员
	void visit2();			// 让visit2函数不可以访问Building中的私有成员
	Building* building;
};

class Building {
	// 让GoodGay类的成员visit函数可以访问Building中的私有成员
	friend void GoodGay::visit();
public:
	// 构造函数
	Building();
public:
	string m_SittingRoom;	// 客厅
private:
	string m_BedRoom;		// 卧室
};

//类外写成员函数(构造函数)
Building::Building() {
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";
}
GoodGay::GoodGay() {
	//创建建筑物对象
	building = new Building;
}

// 参观函数,访问Building中的属性
void GoodGay::visit() {
	cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
	cout << "好基友全局函数 正在访问:" << building->m_BedRoom << endl;
}

void GoodGay::visit2() {
	cout << "好基友全局函数 正在访问:" << building->m_SittingRoom << endl;
}

void test01() {
	GoodGay gg;
	gg.visit();
	gg.visit2();
}

int main() {
	test01();
}

image-20220608102933786

image-20220608102942328

“好基友全局函数 正在访问:” << building->m_SittingRoom << endl;
}

void test01() {
GoodGay gg;
gg.visit();
gg.visit2();
}

int main() {
test01();
}


[外链图片转存中...(img-g1qKWnVt-1683771873281)]

[外链图片转存中...(img-emG2SPlL-1683771873282)]















































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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

01-mysql安装篇(rpm方式安装+压缩包安装)

文章目录 一、rpm方式安装1、检查是否安装了mariadb2、下载mysql3、上传解压4、安装5、检查安装6、开启mysql服务7、登陆mysql8、修改密码设置规则&#xff08;简单型-学习用&#xff09;9、修改密码10、授权远程登陆11、启停mysql命令12、rpm方式安装说明 二、压缩包方式安装V…

前端技术搭建飞机大战小游戏(内含源码)

The sand accumulates to form a pagoda ✨ 写在前面✨ 功能介绍✨ 页面搭建✨ 样式设置✨ 逻辑部分 ✨ 写在前面 上周我们实通过前端基础实现了弹珠游戏&#xff0c;当然很多伙伴再评论区提出了想法&#xff0c;后续我们会考虑实现的&#xff0c;今天还是继续按照我们原定的节…

2023年第三届长三角高校数学建模竞赛】A 题 快递包裹装箱优化问题 详细数学建模过程

1 题目 2022 年&#xff0c;中国一年的包裹已经超过 1000 亿件&#xff0c;占据了全球快递事务量的一半以上。近几年&#xff0c;中国每年新增包裹数量相当于美国整个国家一年的包裹数量&#xff0c; 十年前中国还是物流成本最昂贵的国家&#xff0c;当前中国已经建立起全世界…

阿里云服务器建站教程来了(十分钟网站上线)

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流程&#xff1a; …

布朗运动模拟

布朗运动模拟 文章目录 布朗运动模拟[toc]1 布朗运动定义2 布朗运动模拟3 布朗桥4 带漂移布朗运动5 几何布朗运动 1 布朗运动定义 给定随机过程 { W ( t ) , t ≥ 0 } \{W(t),t \ge 0 \} {W(t),t≥0}&#xff0c;满足以下条件&#xff0c;则称 W ( t ) W(t) W(t)为标准布朗运动…

1 ElasticSearch介绍

全文检索 Elastisearch 研究 目标 了解Elasticsearch的应用场景掌握索引维护的方法掌握基本的搜索Api的使用方法 约束 阅读本教程之前需要掌握Lucene的索引方法、搜索方法 。 1 ElasticSearch介绍 1.1 介绍 官方网址&#xff1a;https://www.elastic.co/cn/products/elas…

【OpenCV】学习课-图像获取与显示(1)!

OpenCV是一个基于Apache2.0许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上。 [1] 它轻量级而且高效——由一系列 C 函数和少量 C 类构成&#xff0c;同时提供了Python、Ruby、MATLA…

JAVA-多态

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 1.多态的概念 2.多态的实现条件 3.重写 总结 1.多态的概念 什么是多态? 通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个…

【仪器控制】LAN Web 浏览器界面!

仪器支持不同的接口和协议进行远程控制。下表给出了概述 LAN web 浏览器界面 &#xff1a; LAN Web 浏览器界面允许轻松配置 LAN 和远程控制 R&S FSW&#xff0c;无需额外的安装要求。 仪器的 LAN 网络浏览器界面可与所有 W3C 兼容的浏览器正常工作。 通过 R&S FSW 的 …

React组件实例state-事件绑定(三)

类组件中的属性 我们看一个简单的类组件实例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>hello_react</title></head><body><!-- 准备好一个“容器” --><div id&q…

Tech Talk | 还原照片不同亮度范围细节——RAW HDR技术

拍照时&#xff0c;你是否遇到过这些情况呢&#xff1f; 拍摄的成片暗区过暗&#xff0c;高亮区域过曝 逆光拍摄中&#xff0c;会出现“鬼影” 暗部噪声偏大导致图像出现瑕疵 ....... 照片的高光和暗区细节得总是不到完美呈现&#xff0c;这是所有拍摄设备都会出现的问题。那么…

淘宝拍立淘多码识别方案总结

本文通过拆解原始问题、发散思路优化等方式&#xff0c;记录了扫一扫从单码到多码识别的技术框架改造及多码识别率优化方案。其中涉及解码SDK的能力、码处理技术链路、码转换算法、降低漏检率策略等设计与实现。 背景与挑战 多码即在同一个界面中同时存在多个条码或二维码&…

国产自研数据库是更新换代首选

伴随着数字经济的高速发展&#xff0c;越来越多的企业都意识到了数据是现代企业最具价值的资产。而与之相对应的是&#xff0c;数据库的重要性也随之水涨船高。 近年来&#xff0c;在席卷全球的云原生大潮中&#xff0c;数据库产业迎来了极为重要的转型升级。特别是在自主创新的…

JVM系列-第7章-对象的实例化内存布局与访问定位

对象的实例化内存布局与访问定位 对象的实例化 大厂面试题 美团&#xff1a; 对象在JVM中是怎么存储的&#xff1f;对象头信息里面有哪些东西&#xff1f; 蚂蚁金服&#xff1a; 二面&#xff1a;java对象头里有什么 对象创建的方式 new&#xff1a;最常见的方式、单例…

真正的智能不仅仅是一个技术问题

智能并不是单一的技术问题&#xff0c;而是一个包括技术、人类智慧、社会制度和文化等多个方面的综合体&#xff0c;常常涉及技术变革、系统演变、运行方式创新、组织适应。智能是指人类的思考、判断、决策和创造等高级认知能力&#xff0c;可以通过技术手段来实现增强和扩展。…

【基础篇】nginx代理、动静分离、路径重写、高可用以及https配置

目录 正向代理 反向代理 负载均衡 负载均衡的策略 动静分离 alias与root UrlRewrite(资源路径重写) 防盗链配置 高可用配置 Https证书配置 安装BBS&#xff08;开源界的鼻祖&#xff09; 正向代理 用户知道nginx服务器的存在&#xff0c;与nginx服务器是一伙的。…

第五十五章 Unity 视频播放

使用视频播放器组件(Video Player)可将视频文件附加到游戏对象&#xff0c;然后在运行时在游戏对象的纹理上播放。首先&#xff0c;我们需要了解视频文件。视频文件的典型文件扩展名包括 .mp4、.mov、.webm 和 .wmv。可将许多不同的视频文件格式导入 Unity 中。Unity 将导入的视…

【Linux】编译器gcc/g++的使用

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;Linux的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录 前言一、gcc/g的介绍二、程序的翻…

基于Vue CLI搭建vue3项目

前言 使用vue官方的脚手架进行搭建Vue CLI 注意&#xff1a;create-vue是基于Vite搭建项目&#xff0c;今天我们还是基于webpack搭建使用vue create 项目名称这个命令 一、步骤 1、 使用默认配置项还是自定义配置 这里我选择自定义 2、 选择需要配置的选项 根据个人进行…

ChatGPT不会很快接管人类工作,AI也不会免费打工

ChatGPT 等大模型的相继发布&#xff0c;让很多人倍感压力&#xff0c;害怕 AI 会很快接管他们的工作。对此&#xff0c;OpenAI 也曾发表过一项研究&#xff0c;表明 ChatGPT 的影响涵盖所有收入阶层&#xff0c;且高收入工作可能面临更大的风险。事实到底如何呢&#xff1f; …