C++基础知识友元friend、友元函数和友元类
为了在类之间进行数据共享时,提高效率,C++引入了友元的概念。友元主要有三个方面的应用:
- 将普通函数声明为类的友元函数;
- 将一个类声明为其他类的友元类;
- 将一个类中的成员函数声明为其他类的友元函数。
下面分别介绍。
1、普通函数声明为友元函数
将一个普通函数,声明为某个类的友元函数后(在函数声明前加上“friend”关键字),该函数就可以访问类中的任何成员。观察下面的代码:
#include<iostream>
using namespace std;class friend_test{private:int a=3; //非静态成员变量static int b; //声明静态成员变量public:friend void friend_func(friend_test &f); //将函数friend_func()函数,声明为该类的友元函数。由于友元函数没有this指针
};
int friend_test::b=4; //定义静态成员变量//friend_func()函数的实现
void friend_func(friend_test &f)
{cout<<"访问基础类friend_test的私有成员变量: "<<f.a<<endl;cout<<"访问基础类friend_test的静态成员变量: "<<friend_test::b<<endl;cout<<"访问基础类friend_test的静态成员变量: "<<f.b<<endl;
}int main()
{friend_test f; //声明friend_test类的对象friend(f); //程序运行正常,按预期输出结果return 0;
}
从上面的程序中可以看出,友元函数访问类的成员变量时,有以下特点:
- 访问静态static成员时,可以通过”类名::变量名”和”对象名::变量名”方式访问;
- 访问非静态成员时,只能通过“对象名::变量名”方式访问。
2、友元类
若将类A 声明为类B的友元类,那么类A中的所有成员函数都可以访问类B中的所有成员;反之,不成立,即友元不是双向的。
观察下面的代码:
#include<iostream>
using namespace std;class A;
class B{public:friend class A; //声明类A为类B的友元类private:int b;
};
class A{public:void func1(B &BB); //声明类A的成员函数void func2(B &BB);
};
void A::func1(B &BB)
{cout<<"访问类B的成员变量: "<<BB.b<<endl;
}
void B::func2(B &BB)
{cout<<"本函数用不到类B的成员变量"<<endl;
}
int main()
{A AA; //声明类A的对象B BB; //声明类B的对象A.func1(BB); //调用类A的成员函数,在成员函数中访问类B的成员变量A.func2(BB);
}
通过以上代码,可以发现类A为类B的友类,类A中所有的成员函数都可以访问类B中的所有成员。那么,此时会带来一个问题,若类A中的某个函数如上面的“func2()”不需要访问类B的成员变量,只有函数“func1()”需要访问类B的成员。
由于友元的引入本来就破坏了“封装”,使得面向对象的颜面有点受损。那么,可以仅仅设置类A的成员函数func1()为类B的友元函数,从而类B的成员对函数“func2()”就不可见了^-^
上面所述就是将类的成员函数声明为其他类的友元函数的目的。
3、类的成员函数声明为其他类的友元函数
正如上面所说,若将类A的某个成员函数”func_A()”声明为类B的友元函数后,函数”func_A”就可以访问类B中的所有成员。
观察下面的例子:
#include<iostream>
using namespace std;class B;
class A{public:void func_A(B &BB); //类A的成员函数void func();
};
//类A的成员函数实现
void A::func()
{cout<<"我只是个普通的宝宝~~~"<<endl;
}
class B{public:friend void A::func_A(B &BB); //将类A的func_A()成员函数声明为类B的友元private:int b=5; //类B的成员变量
};
//类A中为类B友元的成员函数实现,必须放在类B定义之后
void A::func_A(B &BB)
{cout<<"通过类A的成员函数访问类B的成员变量: "<<BB.b<<endl;
}
int main()
{A AA; //类A的对象B BB; //类B的对象A.func(); //访问类A的成员函数A.func_A(); //访问类A的成员函数,为类B的友元
}
通过以上分析,将友元的特点总结如下:
- 由于友元函数没有this指针,访问静态static成员时,可以通过”类名::变量名”和”对象名::变量名”方式访问;
- 访问非静态成员时,只能通过“对象名.变量名”方式访问。
- 虽能提高效率,但破坏了程序的封装,尽量减少friend的使用;
- 在声明类的成员函数为其他类的友元时,函数实现要放在其他类的定义之后。
C++基础知识友元friend、友元函数和友元类相关推荐
- C++:C++语言入门级基础知识考察点回顾之函数、结构体和类
C++:C++语言入门级基础知识考察点回顾之函数.结构体和类 目录 C++的函数 1.函数的定义.调用,全局变量局部变量 1.1.自定义函数求其倒数
- [Python图像处理] 一.图像处理基础知识及OpenCV入门函数
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...
- python程序如何执行死刑_「Python基础知识」Python生成器函数
原标题:「Python基础知识」Python生成器函数 对于程序而言,内存也是很重要的,因为程序中很多数据都是保存在内存中的,如果内存中存储的数据过多,那么系统就会崩溃,这是人们不希望发生的. 可以采 ...
- convert.todatetime指定日期格式_SQL基础知识V2——常用日期函数
点击上方SQL数据库开发,关注获取SQL视频教程 SQL专栏 SQL数据库基础知识汇总 SQL数据库高级知识汇总 日期函数是数据库中经常需要使用到的,本期将常用的几个日期函数给小伙伴做详细的介绍. G ...
- 计算机单招基础知识试题,高职单招《计算机类专业基础知识》正式试卷
高职单招<计算机类专业基础知识>正式试卷 20XX年高考<计算机类专业基础知识>试卷 一. 单项选择题(在每小题的四个备选答案中,选出一个正确答案,并将正确回答的序号填在题干的 ...
- C++_类和对象_对象特性_友元_成员函数做友元---C++语言工作笔记054
然后我们接着看友元,这次我们来看这个类的成员函数来做友元函数. 还是直接去看例子吧. 写个GoodGay这个类,然后里面有 构造方法,声明一个,Building 这个类的指针,building. 因为 ...
- decode函数python在哪里_Python基础知识——encode和decode函数
以前我们介绍过,Python2.x中默认的编码的基础类型是unicode编码的类型,在Python3.x才转化为基于unicode的字符串. 那么我们在Python2.x的学习中就会遇到各种各样的编码 ...
- C++_类和对象_对象特性_友元_全局函数做友元_在类中声明友元权限的全局函数来访问_类中的private权限的变量---C++语言工作笔记052
然后我们再来看友元,友元,其实就类似于, 比如一个建筑类,这里面有,客厅有卧室, 那么客厅是public的,大家都能访问,但是卧室是private的,外人不能访问 但是,如果是我的朋友,.我想让他访问 ...
- 【Python培训基础知识】Python生成器函数
对于程序而言,内存也是很重要的,因为程序中很多数据都是保存在内存中的,如果内存中存储的数据过多,那么系统就会崩溃,这是人们不希望发生的. 可以采用生成器推导式来解决内存不足的问题.例如,利用生成器推导 ...
- 基础知识——用户输入和函数(五)
基础点 用户输入:message=input("用户输入:") 函数传递列表参数,并且禁止修改列表:列表为a,函数为func(),调用func(a[:]),此时传递的是列表a的副本 ...
最新文章
- CopyOnWriteArrayList实现原理及源码分析
- Javascript中的深拷贝和浅拷贝
- 利用反射,泛型,静态方法快速获取表单值到Model。
- spark 2.4.5 简单使用
- mongoDB 从单节点迁移到分布式集群 遇到的问题
- 【CodeForces - 438D】The Child and Sequence(线段树区间取模操作)
- linux错误自动报告工具,linux – 关闭abrt的电子邮件通知(自动错误报告工具)
- 华为 招聘 状态 查看_英特尔放弃5G芯片研发:三星受益;爱立信2019年Q1净利润约2.51亿美元;华为也将要与高通和解;天津首个5G电话成功打通...
- Add_List2Dictionay
- AVR系列之TWI功能测试
- linux mv复制命令,linux中删除复制移动文件rm,mv,cp命令详解linux操作系统 -电脑资料...
- 学python买什么书-关于 Python 的经典入门书籍有哪些?
- 个人用户上网需要有计算机电话线,个人用户上网需要有计算机、电话线、用户账号和口令,以及______。...
- office图标显示异常和新建时图标没有显示等问题解决
- Linux查看cuda版本
- “神舟八号”飞船将瞄准11月1日5时58分发射
- 苹果手表支持心电图功能,可能还是逃不过噱头的命运
- win10装的AutoCAD 2012版,右上角最小化不显示的解决办法
- Airbnb短租数据分析报告
- 研究生被导师嫌弃是种怎样的体验?写的太真实了...
热门文章
- sharepoint 2013基于AD的Form表单登录(三)——选择用户时,屏蔽掉AD。
- 编译Ngnix遇到的问题,查看程序依赖的库文件
- 园区网VLAN应用实例
- linux 笔记之一mysql源码包安装
- 学成在线--23.课程图片管理(上传图片)
- 调整标志位方法oracle,面试题(二)(示例代码)
- 光源时间_缩短背光源的使用寿命的原因
- mysql中如何把两个查询结果列数不同并成一张表_MySQL
- JDBC笔记-李伟杰版
- 计算机表格复制粘贴后不变,excel表格复制粘贴后格式不变