C++友元类和友元函数

2023-05-16

特点:

  • 能访问私有成员
  • 破坏封装性
  • 友元关系不可传递。若B是A的友元,C是B的友元,但C不一定是A的友元,要看类中是否有申明。
  • 友元关系的单向性。若A是B的友元,但B不一定是A的友元,要看类中是否申明。
  • 友元声明的形式及数量不受限制

为什么需要友元:

        在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。

友元的作用:

       友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元的三种实现:

  1. 全局函数做友元
#include <iostream>
#include <string>
using namespace std;
// 房屋类
class Building
{
	// 告诉编译器 laoWang全局函数是 Building类  的好朋友,可以访问Building对象的私有成员
	friend void laoWang1(Building *building);
	friend void laoWang2(Building &building);
	friend void laoWang3(Building building);
public:
	Building()
	{
		m_SittingRoom = "客厅";
		m_BedRoom = "卧室";
	}
	string m_SittingRoom;	// 客厅
private:
	string m_BedRoom;		// 卧室
};
//全局函数
void laoWang1(Building *building)
{
	cout << "隔壁老王 全局函数 正在访问:(地址传递) " << building->m_SittingRoom << endl;
	cout << "隔壁老王 全局函数 正在访问:(地址传递) " << building->m_BedRoom << endl;
}
void laoWang2(Building &building)
{
	cout << "隔壁老王 全局函数 正在访问:(引用传递) " << building.m_SittingRoom << endl;
	cout << "隔壁老王 全局函数 正在访问:(引用传递) " << building.m_BedRoom << endl;
}

void laoWang3(Building building)
{
	cout << "隔壁老王 全局函数 正在访问:( 值传递 ) " << building.m_SittingRoom << endl;

	cout << "隔壁老王 全局函数 正在访问:( 值传递 ) " << building.m_BedRoom << endl;
}
void test()
{
	Building building;
	laoWang1(&building);
	laoWang2(building);
	laoWang3(building);
}
int main()
{
	test();
}
//结果:
//隔壁老王 全局函数 正在访问:(地址传递) 客厅
//隔壁老王 全局函数 正在访问:(地址传递) 卧室
//隔壁老王 全局函数 正在访问:(引用传递) 客厅
//隔壁老王 全局函数 正在访问:(引用传递) 卧室
//隔壁老王 全局函数 正在访问:( 值传递 ) 客厅
//隔壁老王 全局函数 正在访问:( 值传递 ) 卧室
  1. 类做友元
#include <iostream>
#include <string>
using namespace std;
// 类作友元
class Building;
class LaoWang
{
public:
	LaoWang();
	void visit();	//参观函数  访问Building中的属性
	Building * building;
private;
};
// 房屋类
class Building
{
	// 告诉编译器,LaoWang类是Building类的好朋友,可以访问Building类的私有成员
	friend class LaoWang;
public:
	Building();
	string m_SittingRoom;	// 客厅
private:
	string m_BedRoom;		// 卧室
};
// 类外定义成员函数
Building::Building()
{
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";
}
LaoWang::LaoWang()
{
	// 创建建筑物对象
	building = new Building;
}
void LaoWang::visit()
{
	cout << "隔壁老王LaoWang类正在访问:" << building->m_SittingRoom << endl;
	cout << "隔壁老王LaoWang类正在访问:" << building->m_BedRoom << endl;
}
void test()
{
	LaoWang lw;
	lw.visit();
}
int main()
{
	test();
	return 0;
}
//结果
//隔壁老王LaoWang类正在访问:客厅
//隔壁老王LaoWang类正在访问:卧室
  1. 成员函数做友元
#include <iostream>
#include <string>

using namespace std;

class Building;

class LaoWang
{
public:

	LaoWang();
	void visit1();	//让visit1()函数   可以 访问Building中的私有成员
	void visit2();	//让visit2()函数 不可以 访问Building中的私有成员

	Building *building;

private:

	
};

class Building
{
	// 告诉编译器,LaoWang类下的visit1()函数是Building类的好朋友,可以访问Building的私有成员
	friend void LaoWang::visit1();

public:
	Building();

	string m_SittingRoom;	//客厅
private:

	string m_BedRoom;		//卧室
};


LaoWang::LaoWang()
{
	building = new Building;
}

void LaoWang::visit1()
{
	cout << "隔壁老王LaoWang类中的visit1()函数正在访问:" << building->m_SittingRoom << endl;
	cout << "隔壁老王LaoWang类中的visit1()函数正在访问:" << building->m_BedRoom << endl;
}

void LaoWang::visit2()
{
	cout << "隔壁老王LaoWang类中的visit2()函数正在访问:" << building->m_SittingRoom << endl;
	//cout << "隔壁老王LaoWang类中的visit2()函数正在访问:" << building->m_BedRoom << endl;	//错误!私有属性不可访问
}

Building::Building()
{
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";
}

void test()
{
	LaoWang lw;
	
	lw.visit1();

	lw.visit2();
}

int main()
{
	test();
	
	return 0;
}
//结果
//隔壁老王LaoWang类中的visit1()函数正在访问:客厅
//隔壁老王LaoWang类中的visit1()函数正在访问:卧室
//隔壁老王LaoWang类中的visit2()函数正在访问:客厅
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++友元类和友元函数 的相关文章

  • 强化学习实战——Q learning 实现倒立摆

    倒立摆参数以及数学模型 首先是写一个倒立摆的AGENT模型 pendulum env py import numpy as np import matplotlib pyplot as plt import matplotlib impor
  • dependencies.dependency

    依赖包有两个 xff0c 根据最下一行的提示找到项目的pom xml文件找到依赖
  • Vue3---语法初探

    目录 hello world 实现简易计时显示 反转字符串 显示隐藏 了解循环 了解双向绑定实现简易记事 设置鼠标悬停的文本 组件概念初探 xff0c 进行组件代码拆分 hello world 最原始形态 xff0c 找到 id 为 roo
  • MySQL实战解析底层---普通索引和唯一索引,应该怎么选择

    目录 前言 查询过程 更新过程 change buffer 的使用场景 索引选择和实践 change buffer 和 redo log 前言 在不同的业务场景下 xff0c 应该选择普通索引 xff0c 还是唯一索引 xff1f 假设你在
  • 准备离开:致消散的梦想

    学到现在基本都是悲剧以前的队友现在大多放弃了初心以前的好学长现在摆烂和失败开学时的场景再也见不到了大一开学开启OJ xff0c 那是一个永远绚丽的夜晚不管是学长还是同学 xff0c 都在那时期待未来 xff0c 欲力竭以圆其说而不是现在的颓
  • MySQL实战解析底层---MySQL为什么有时候会选错索引

    目录 前言 优化器的逻辑 索引选择异常和处理 前言 在 MySQL 中一张表其实是可以支持多个索引的但是你写 SQL 语句的时候 xff0c 并没有主动指定使用哪个索引也就是说 xff0c 使用哪个索引是由 MySQL 来确定的不知道你有没
  • 二叉搜索树

    目录 定义简介 查找结点 插入结点 删除结点 排序 二叉搜索树的效率 二叉搜索树的退化 二叉搜索树常见应用 定义简介 二叉搜索树 Binary Search Tree 满足以下条件 xff1a 1 对于根结点 xff0c 左子树中所有结点的
  • AVL 树

    目录 介绍 结点高度 结点平衡因子 AVL 树旋转 右旋 左旋 先左后右 先右后左 旋转的选择 插入结点 删除结点 查找结点 AVL 树典型应用 介绍 在进行多次插入与删除操作后 xff0c 二叉搜索树可能会退化为链表此时所有操作的时间复杂
  • 红黑树(更高级的二叉查找树)

    目录 介绍及性质 红黑树的基本定义 黑高度 时间复杂度 接近于 平衡 操作 红黑树的旋转 红黑树中插入新结点 红黑树中删除结点 红黑树与AVL树的区别 介绍及性质 红黑树 xff08 R B TREE xff0c 全称 xff1a Red
  • MySQL实战解析底层---怎么给字符串字段加索引

    目录 所谓前缀索引 前缀索引对覆盖索引的影响 其他方式 所谓前缀索引 现在 xff0c 几乎所有的系统都支持邮箱登录 xff0c 如何在邮箱这样的字段上建立合理的索引 xff0c 是今天要讨论的问题假设 xff0c 你现在维护一个支持邮箱登
  • Spring Security --- 3.5.7版本升级

    目录 WebSecurityConfigurerAdapter 被弃用 configure WebSecurity web 已经弃用 configure AuthenticationManagerBuilder auth 已经弃用 Spri
  • 双系统下,ubuntu20.04循环登录问题解决记录

    什么是循环登录 xff1a 开机登录页面 xff0c 输入密码后 xff0c 未提示密码错误 xff0c 黑屏一秒继续出现登录页面 xff0c 死循环 由于不能进桌面系统 xff0c 我们只能尝试在终端解决问题了 ctrl 43 alt 4
  • Spring Security --- 快速入门

    概念 Spring Security是一个功能强大且高度可定制的 xff0c 主要负责为Java程序提供声明式的 身份验证和访问控制 的安全框架Spring Security的底层主要是 基于 Spring AOP 和 Servlet 过滤
  • Spring Security --- 基于内存模型创建用户角色

    授权实现方式 基于内存模型实现授权基于默认数据库模型实现授权基于自定义数据库模型实现授权 基于内存模型创建用户角色 在Spring Security4 x版本中 xff0c 登陆的用户有一个默认的ROLE USER角色但是在Spring S
  • Spring Security --- authorizeRequests配置

    目录 自定义配置类之访问权限 匹配顺序规则 访问控制包含 访问控制url匹配 访问控制方法 角色 权限判断 使用注解进行角色权限控制 自定义配置类之访问权限 http authorizeRequests 主要是对url进行访问权限控制通过这
  • 手写Spring框架-前奏-注解与自定义注解

    目录 注解 介绍 功能 分类 注解处理器类库 自定义注解 常用元注解 自定义 注解 介绍 提供一种为程序元素设置元数据的方法用来将任何的信息或元数据 xff08 metadata xff09 与程序元素 xff08 类 方法 成员变量等 x
  • 手写Spring框架-前奏-反射获取Annotation

    目录 所谓反射 反射机制的作用 反射依赖reflect和Class 反射依赖的Class Class类的特点 获取Class对象的三种方式 获取类的构造方法并使用 获取类的成员变量并使用 获取类的成员方法并使用 问题引入 解析类的注解 解析
  • 数据结构的加强甜点-序列1

    目录 尾递归 问题 介绍 特点 原理 答案 数组栈堆内存分配 前言 分析 再分析 所谓多维数组 程序局部性原理应用 尾递归 问题 在空间复杂度这块 xff0c 有个O n 示例如下 xff1a void recur int n if n 6
  • Spring Security --- formLogin配置

    目录 环境准备 配置自定义登录表单页面 配置登录成功的跳转页面方式 配置登录失败的跳转页面方式 前端表单参数获取 CustomWebSecurityConfigurerAdapter配置类代码示例 环境准备 创建springboot项目引入
  • 手写Spring框架---IOC容器实现

    目录 框架具备的最基本功能 实现容器前奏 创建注解 提取标记对象 extractPacakgeClass里面需要完成的事情 获取项目类加载器的目的 为什么不让用户传入绝对路径 类加载器ClassLoader 统一资源定位符URL Class

随机推荐

  • ECharts---X轴文字显示不全

    原因 xff1a X轴标签文字过多导致显示不全解决方法 xff1a 一 xAxis 中添加 xAxis axisLabel 属性 axisLabel是用来设置x轴的刻度以及一些参数的设置 xff1a 1 interval设置的是间隔数 xf
  • MyBatis-plus二级缓存整合Redis 分页中Count缓存createCacheKey 与 getCountCacheKey 缓存Hash值不一致导致数组越界

    当前使用版本 新版本同样存在此问题 MyBatis plus 3 4 1该问题是如何引起的 在使用Redis代理二级缓存中发现存在两个Count缓存 xff0c 并且总是获取错的Count缓存Count缓存createCacheKey的 与
  • Ubuntu16.04安装谷歌浏览器

    Ubuntu16 04安装谷歌浏览器 Ubuntu16 04安装谷歌浏览器分为3步 xff1a 1 下载安装包 2 安装谷歌浏览器 3 启动谷歌浏览器 1 下载谷歌浏览器安装包 使用Ubuntu系统自身携带的火狐浏览器 xff0c 访问谷歌
  • Mybatis一级缓存详解

    目录 一级缓存 一级缓存的组织 一级缓存的生命周期 一级缓存的工作流程 Cache接口的设计以及CacheKey的定义 一级缓存的性能分析 一级缓存与Spring 事务一级缓存存在的弊端 官方文档分析 Spring通过Mybatis调用数据
  • Servlet 三角形判断以及面积计算

    题目描述 xff1a 用html和servlet编程实现输入三角形的三个边长并计算和输出三角形的面积 要求如下 1 编写一个inputhtml页面 xff0c 页面中包括输入三个边长和和提交按钮的表单 2 编写一个文件名为TriangleS
  • Warning: Stopping docker.service, but it can still be activated by: docker.socket解决方案

    文章目录 问题描述 xff1a 1 解决方案一2 解决方案二 xff1a 问题描述 xff1a 当容器开启自动启动时 xff0c 我们想要关闭docker的时候发现会出现 xff1a Warning Stopping docker serv
  • 虚拟机Ubuntu安装vs code操作步骤

    1 在浏览器上搜索 xff1a https code visualstudio com Download 2 选择 deb 按钮下载 3 下载完成后打开文件 4 右键安装包 xff0c 选择打开方式 xff1a 软件安装 点击安装 xff0
  • ping不通Linux服务器的原因?

    ping命令是各种操作系统中经常会用到的一个网络命令 xff0c 也是一个通信协议 xff0c 主要用来测试目标主机的连通性 xff0c 检查网络是否连通 问题 xff1a 那ping不通Linux系统服务器是什么原因呢 xff1f 总结
  • RHCE第二天

    作业 xff1a 1 配置chrony时间服务器 xff0c 确保客户端主机能和服务主机同步时间 两台机器 第一台机器作为时间服务器从ntp aliyun com同步时间 xff08 注意包含意外情况 xff0c 如果不能上外网 xff0c
  • ubuntu20.04版本 安装ros1与px4、mavros、QGroundControl

    基于个人安装时的操作以及所浏览的链接 xff0c 仅供参考 文章目录 前言一 pandas是什么 xff1f 二 使用步骤 1 引入库2 读入数据总结 前言 使用ubuntu下载ros px4似乎是一件十分繁琐以及困难的事情 xff0c 但
  • 无用的知识--定时提醒(go语言小工具)

    遇到喜欢的事情总是欲罢不能 xff0c 一不小心就酿成了打错 xff0c 比如说在B站上学习 xff08 卷 xff09 过度 xff0c 错过了重要的事情 不用担心 xff0c 今天分享go语言写一个windows系统中定时提醒小工具 p
  • 重装Office后打开Powerpoint和excel提示找不到VCRUNTIME140_1.dll的解决办法(亲测成功,简单有效)

    1 下载VCRUNTIME140 1 dll xff08 可搜索下载途径 xff09 2 将其复制到OFFICE安装目录 xff0c 如下 C Program Files Microsoft Office16 3 再次打开即成功 xff01
  • ERROR:zygote_host_。。。。。Running as root without --no-sandbox is not supported.

    安装好google后 xff0c 在命令行输入google chrome后出现 xff0c ERROR zygote host impl linux cc 89 Running as root without no sandbox is n
  • 【IOT开发】蓝牙模块与PC连接通讯实验

    这是在一个项目中 xff0c 需要开发 windows APP xff0c 通过蓝牙与下位机通讯 之前接触过的一些蓝牙项目 xff0c 大多是 模块与模块 通讯 xff0c 也见过很多模块 手机通讯的教程 xff0c 但PC端直接与蓝牙模块
  • Linux安装JDK详细教程(附图)

    Linux安装JDK详细教程 xff08 图文教程 xff09 这里介绍两种方式 xff1a yum安装方式和手动安装 1 yum安装 1 1 查看JDK版本 xff0c 找到你想要安装的JDK版本 xff0c 这里以 JDK1 8 为例
  • AD布线后批量改线宽

    最近在学习AD画板 xff0c 打算布线结束后再改线宽 xff0c 遇到了一些问题 xff0c 经过网上的资料已经解决 首先 xff0c 右键空白处 xff0c 选择第一个 查找相似对象 然后用十字标选择想要更改的线 在弹出的框中更改 NE
  • 使用springboot启动类报错: 找不到或无法加载主类怎么解决?

    出现问题的原因是 xff1a 在使用springboot启动类时 xff0c 并没有写错代码和注解 xff0c 然后它还是报错找不或无法加载主类 解决此问题的办法 就是 xff0c 重新在项目结构中的Modules吧项目移除再次加载进了即可
  • 【iOS】---pthread,NSThread

    在iOS中多线程开发有四种方式 xff0c 在之前我们浅浅了解了一下GCD xff0c 这期来看看pthread和NSThread pehread pthread简介 pthread 是一套通用的多线程的 API xff0c 可以在Unix
  • 如何关闭windows11 Defender防火墙

    windows Defender是windows系统自带的防火墙 xff0c 但是由于它太过于敏感 xff0c 导致很多软件 xff0c 程序被误杀 一般默认开启时 xff0c Denfender防火墙拦截时会弹出提示 下面教大家如何关闭w
  • C++友元类和友元函数

    特点 xff1a 能访问私有成员 破坏封装性 友元关系不可传递 若B是A的友元 xff0c C是B的友元 xff0c 但C不一定是A的友元 xff0c 要看类中是否有申明 友元关系的单向性 若A是B的友元 xff0c 但B不一定是A的友元