详解C++ friend关键字
详解C++ friend关键字
http://blog.csdn.net/lwbeyond/article/details/7591415
概述:
1. 为什么要使用友元?
通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为 public( 共用的) ,然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它;另一种方法是利用 C++ 的 friend 修饰符,可以让一些你设定的函数能够对这些私有或保护数据进行操作。
2. 使用友元有哪些缺点?
使用友元的同时也破坏了类的封装特性,这即是友元最大的缺点。当对外声明为友元后,你的所有细节全部都暴露给了对方。
就好像你告诉你朋友你很有钱这个密秘,进而又把你有多少钱,多少古董,多少家产,多少小妾等等所有的家底全给他说了。
3. 友元怎样理解?
定一个友元函数,或是友元类,就是告诉对方:我的所有元素对你是开放的。这种 friend 是建立在灰常灰常灰常信任对方的基础上的。
一. 普通函数做为类的一个友元函数
在类里声明一个普通函数,在前面加上 friend 修饰,那么这个函数就成了该类的友元。
这时这个普通函数可以访问该类的一切成员。
代码如下:
- #include <iostream >
- using namespace std;
- class MyClass
- {
- public :
- MyClass(string name)
- {
- m_name = name;
- }
- //声明一个友元函数
- friend void Display(MyClass &mycalss);
- Protected:
- string m_name;
- };
- //定义这个友元函数
- //写成 void MyClass::Display(MyClass &mycalss)
- void Display(MyClass &mycalss)
- {
- cout << "Access Protected data : "<< mycalss.m_name << endl;
- }
- //测试
- int main(int argc,char* argv[])
- {
- MyClass test("Class A");
- Display(test);
- return 0;
- }
说明:
1. 声明这个友元函数可以在任何地方,可以在 public、protected 当然也可以在 privated 里。
2. 在这个友元函数里,你可以访问这个类里的所有的成员,所有的成员函数,而不管它是不是 public、protected 或 privated 的。
3. 定义友元函数时,不能写成 void MyClass::Display(MyClass &mycalss) 这点要注意。
二. 一个普通函数可以是多个类的友元函数
在每个类里面都有一个友元函数的声明,声明可以有多个,但定义只能有一个。
代码如下:
- #include <iostream >
- using namespace std;
- class MyClass_B;
- class MyClass_A
- {
- public:
- MyClass_A(string name)
- {
- m_name = name;
- }
- //声明一个友元函数
- friend void Display(MyClass_A &myA, MyClass_B &myB);
- private:
- string m_name;
- };
- class MyClass_B
- {
- public:
- MyClass_B(string name)
- {
- m_name = name;
- }
- //注意,又声明一个友元函数
- friend void Display(MyClass_A &myA, MyClass_B &myB);
- private:
- string m_name;
- };
- //定义这个友元函数
- void Display(MyClass_A &myA, MyClass_B &myB)
- {
- cout << "MyClass A : "<< myA.m_name << endl;
- cout << "MyClass B : "<< myB.m_name << endl;
- }
- //测试代码
- int main(int argc,char* argv[])
- {
- MyClass_A testA("Class A");
- MyClass_B testB("Class A");
- Display(testA, testB);
- return 0;
- }
同样的,这个友元函数,可以访问这两个类的所有元素。
三. 一个类的成员函数也可以是另一个类的友元
从而可以使得一个类的成员函数可以操作另一个类的数据成员
- #include <iostream >
- using namespace std;
- class MyClass_B;
- //A 类
- class MyClass_A
- {
- public:
- MyClass_A(string name)
- {
- m_name = name;
- }
- void Function(MyClass_B &myB);
- private:
- string m_name;
- };
- //B 类
- class MyClass_B
- {
- public:
- MyClass_B(string name)
- {
- m_name = name;
- }
- //友元函数声明,注意和普通函数的区别
- friend void MyClass_A::Function(MyClass_B &myB);
- private:
- string m_name;
- };
- //函数定义
- void MyClass_A::Function(MyClass_B &myB)
- {
- cout<<myB.m_name<<endl;
- }
- //测试代码
- int main(int argc,char* argv[])
- {
- MyClass_A testA("Class A");
- MyClass_B testB("Class B");
- testA.Function(testB);
- return 0;
- }
我们可以看到,B 类,对 A 类其中的一个函数开放,其结果是这个函数可以访问 B 类的所有元素。
四. 整个类也可以是另一个类的友元
友类的每个成员函数都可以访问另一个类的所有成员。
示例代码如下:
- #include <iostream >
- using namespace std;
- //类 A
- class MyClass_B;
- class MyClass_A
- {
- public:
- MyClass_A(string name)
- {
- m_name = name;
- }
- //友元类声明
- friend class MyClass_B;
- private:
- string m_name;
- };
- //类 B
- class MyClass_B
- {
- public:
- MyClass_B(string name)
- {
- m_name = name;
- }
- void Display(MyClass_A &myA);
- private:
- string m_name;
- };
- //成员函数
- void MyClass_B::Display(MyClass_A &myA)
- {
- cout<<myA.m_name<<endl; //访问A的私有成员
- MyClass_A test("test");
- cout<<test.m_name<<endl; //好像A的所有元素在B里都存在一样
- }
- //测试代码
- int main(int argc,char* argv[])
- {
- MyClass_A testA("Class A");
- MyClass_B testB("Class B");
- testB.Display(testA);
- return 0;
- }
此时B可以访问A的所有元素,就好像A在B里面一样。
五. 总结
简单的说就是:声明一个友元函数或者是友元类,就是要把自己完全暴露给对方。
转载于:https://www.cnblogs.com/honeybusybee/p/5259265.html
详解C++ friend关键字相关推荐
- 、简述global关键字的作用_详解static inline关键字
详解static inline关键字 本文章为知乎用户 @徐yang哟 原创,禁止抄袭! 灵感来源 在查stm32的LL库部分函数的API时,有时会查到这种函数: __STATIC_INLINE vo ...
- C++/C语言申请动态空间的详解【new关键字、malloc关键字、delete和free关键字】
文章目录 [1] C++ ->new关键字 [2] C语言->malloc关键字 [3]C++/C->delete和free关键字 [1] C++ ->new关键字 new: ...
- 详解static inline关键字
本文章为知乎用户 @徐yang哟 原创,禁止抄袭! 灵感来源 在查stm32的LL库部分函数的API时,有时会查到这种函数: __STATIC_INLINE void LL_GPIO_SetPinOu ...
- Java线程详解(10)-volatile关键字
Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volatile 变量所需的编码较少,并 ...
- C++ 中explicit关键字详解
展开 explicit关键字的作用 使用情况 类型转换函数 单操作数构造函数 同时出现拷贝构造函数和类型转换函数 拷贝构造函数 总结 参考文献 explicit关键字的作用 explicit关键字在写 ...
- mysql explain详解_数据库mysql(1)——B+TREE索引原理
一.B+Tree索引详解 1.什么是索引? 索引:加速查询的数据结构. 2.索引常见数据结构: #1.顺序查找: 最基本的查询算法-复杂度O(n),大数据量此算法效率糟糕. #2.二叉树查找(bina ...
- python镜像下载包_python包详解
干货大礼包!21天带你轻松学Python(文末领取更多福利) 点击查看课程视频地址 本课程来自于千锋教育在阿里云开发者社区学习中心上线课程<Python入门2020最新大课>,主讲人姜伟. ...
- Linux sed 删除行命令常见使用详解
Linux sed d命令常见使用案例 声明与简介 sed:Stream Editor文本流编辑,sed是一个"非交互式的"面向字符流的编辑器.本文主要以实际的数据来介绍sed的d ...
- shell编程之进阶篇三常见命令详解
常见命令详解 接下来我们介绍一些shell脚本中经常使用的linux命令:grep.sed.awk.find grep命令详解 grep命令是我们常用的一个强大的文本搜索命令. 命令格式详解 grep ...
- 什么是黑帽SEO?20种黑帽手法详解。
这次小编为大家整理了20种黑帽技术,内容较多也比较全面,导致篇幅过长.为了方便大家阅读,所以将其分成两篇文章分别发布,另一篇文章篇我也会马上发布到主页小伙伴们可以到小编的个人主页查看哦,接下来小编就为 ...
最新文章
- 通过打印学习Linux内核之sysfs(1)
- solr 英文模拟mysql like查询xml_Solr之精确、匹配、排序、模糊查询-yellowcong
- poj -- 2288 Islands and Bridges
- boost::hash_range相关的测试程序
- 剖析java中的String之__拼接
- JavaScript(js)/上
- 数据线给电脑联网是什么原理_物联网孵化的产物——条码扫描器
- 数字ToString作为货币显示并且带小数
- 统一建模语言UML轻松入门之用例
- WMPLib.WindowsMediaPlayer 的用法
- 热点 | Excel不“香”了,数据分析首选Python!
- 硬核黑科技、技术大咖、AI 音乐节……科大讯飞全球 1024 开发者节太燃了!
- BeamSearch的原理和实现
- Gentoo解决Windows双系统时间不同步的问题
- dataframe分组函数groupby
- python filter 求100以内素数
- 卸载软件时,出现解压缩支持文件时出错,灾难性故障--转载
- facebook登录我游戏_Facebook对我的位置了解多少
- 怎么禁用计算机的文件共享,怎么关闭掉电脑共享文件
- Windows10 怎么添加开机启动项