博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++之friend关键字
阅读量:4299 次
发布时间:2019-05-27

本文共 2751 字,大约阅读时间需要 9 分钟。

友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。通过友元,一个不同函数或另一个类中的成员函数可以访问类中的私有成员和保护成员。

友元的声明以关键字friend开始,只能出现在类定义的内部。因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。

友元的正确使用能提高程序的运行效率,但同时也破坏了类的封装性和数据的隐藏性,导致程序可维护性变差。

普通函数友元函数

友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:

friend 类型 函数名(形式参数);

友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。

友元函数的调用与一般函数的调用方式和原理一致。

#include 
using namespace std;class A{private: int a;public: int get_a(){ return this->a; } friend void set_a(A &a,int aa){ a.a = aa; }};int main() { A a; set_a(a,1);// a.set_a(a,2); // 报错 cout<
<

运行结果:

1

一个函数可以是多个类的友元函数,只需要在各个类中分别声明。

#include 
using namespace std;class B;class A{private: int a;public: int get_a(){ return this->a; } friend void set_ab(A &a,int aa,B &b,int bb);};class B{private: int b;public: int get_b(){ return this->b; } friend void set_ab(A &a,int aa,B &b,int bb);};void set_ab(A &a,int aa,B &b,int bb){ a.a = aa; b.b = bb;}int main() { A a;B b; set_ab(a,1,b,2); cout<
<<" "<
<

运行结果:

1 2

一个类的函数是另一个类的友元

将一个类B的成员函数声明为类A的友元函数,使得可以通过该成员函数访问类A的私有成员。只有当一个类的定义已经被看到时它的成员函数才能被声明为另一个类的友元。

#include 
using namespace std;class A; // 前向声明class B{public: void set_a(A &a,int aa);};class A{private: int a;public: int get_a(){ return this->a; } friend void B::set_a(A &a,int aa);};void B::set_a(A &a,int aa){ a.a = aa;}int main() { A a;B b; b.set_a(a,1); cout<
<

运行结果:

1

友元类

友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。

当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:

friend class 类名;

其中,friendclass是关键字,类名必须是程序中的一个已定义过的类。

#include 
using namespace std;class A{private: int a;public: int get_a(){ return this->a; } friend class B;};class B{public: void set_a(A &a,int aa){ a.a = aa; }};int main() { A a;B b; b.set_a(a,1); cout<
<

运行结果:

1

其他

1. 友元函数与成员函数的区别

  • 成员函数有this指针,而友元函数没有this指针
  • 友元函数不能被继承

2. 使用友元类时注意:

* 友元关系不能被继承。
* 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
* 友元关系不具有传递性。若类B是类A的友元,类CB的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

3. 两个类如何通过友元声明互相访问对方的非公有成员?

#include 
using namespace std;class B;class A{private: int a;public: int get_a(){ return this->a; } friend class B; void set_b(B &b,int bb);};class B{private: int b;public: int get_b(){ return this->b; } void set_a(A &a,int aa){ a.a = aa; } friend void A::set_b(B &b, int bb);};void A::set_b(B &b, int bb){ b.b = bb;}int main() { A a;B b; b.set_a(a,1); a.set_b(b,2); cout<
<<" "<
<

运行结果:

1 2

参考链接

转载地址:http://hhsws.baihongyu.com/

你可能感兴趣的文章
mac os本地通过跳板机可视化连接服务器的mysql、mongodb、redis
查看>>
Python创建不可变的类实例
查看>>
Ajax发送、上传文件,Django后端接收、获取文件
查看>>
requests模块访问api接口小记,requests.request、requests.get和requests.post
查看>>
Python解决中文和空格对齐问题
查看>>
用Python的mutagen模块获取MP3音频文件的时长
查看>>
利用Python的pydub模块将二进制音频保存成普通的MP3、WAV文件
查看>>
解决安装oh-my-zsh后workon切换虚拟环境命令不起作用
查看>>
Python日志logging的levelname格式化参数1.1s小记
查看>>
pytest-cov插件计算单元测试代码覆盖率
查看>>
ubuntu虚拟机VMware桥接模式无法自动化获取IP的解决方法
查看>>
Python debug 报错:SystemError: unknown opcode
查看>>
Python将树结构转换成字典形式的多级菜单结构,写入json文件
查看>>
基于Python镜像制作讯飞语音实时识别docker镜像记录
查看>>
关闭linux防火墙让windows宿主机访问ubuntu虚拟机web服务以及docker
查看>>
pycharm 找不到同目录文件,但是终端中正常的小记
查看>>
安装了grpc但是无法导入:ImportError: No module named 'grpc'
查看>>
Python3调用腾讯实时语音识别示例
查看>>
Python中logging模块的基本用法
查看>>
Python查看第三方库、包的所有可用版本,历史版本
查看>>