前言

类中的成员通过权限控制符实现了数据的封装,若对象要访问类中的私有数据,则只能通过成员函数实现。这种方式实现了数据的封装却增加了开销,有时候需要通过外部函数或类直接访问其他类的私有成员,为此C++提供了友元,使用友元可以访问类中的所有成员,函数和类都可以作为友元。

一 友元函数

友元函数可以是类外定义的函数或者是其他类中的成员函数,若在类中声明某一函数为友元函数,则该函数可以操作类中的所有数据。

接下来分别讲解类外定义的普通函数作为类的友元函数和类成员函数作为友元函数的用法。

普通函数作为友元函数

将普通函数作为类的友元函数,在类中使用friend关键字声明该普通函数就可以实现,友元函数可以在类中任意位置声明。普通函数作为类的友元函数的声明格式如下所示:

class 类名
{ friend 函数返回值类型 友元函数名(形参列表); ...   //其他成员
} 

如下所示,原本,在friend_show中是不可以访问类myclass的私有成员变量num的。但是将friend_show设置为myclass的友元函数以后,就可以访问了

#include <iostream>
#include <iomanip>
using namespace std;class myclass{friend void friend_show(myclass &c);
public:myclass(int n):num(n){cout << "class init" << endl;}~myclass(){cout << "class destroy" << endl;}void show(){cout << "num = " << setw(5) <<setfill(' ') << num <<endl;}
private:int num;
};
void friend_show(myclass &c)
{cout << "num = " << setw(5) <<setfill(' ') << c.num <<endl;
}int main()
{myclass c(10);c.show();friend_show(c);
}

运行结果:

class init
num =    10
num =    10
class destroy

如何将类中的友元注释掉,编译就会报错:如下图所示,提示num是一个私有成员。

其他类的成员函数作为友元函数

代码如下所示:

注意,void show(myclass &c)函数的实现部分,要写在class myclass类体的后面,否则会提示错误。

#include <iostream>
#include <iomanip>
using namespace std;class myclass;
class friendclass{
public:friendclass(){}void show();void show(myclass &c);
};
class myclass{
friend void friendclass::show(myclass &c);
public:myclass(int n):num(n){cout << "class init" << endl;}~myclass(){cout << "class destroy" << endl;}void show(){cout << "num = " << setw(5) <<setfill(' ') << num <<endl;}
private:int num;
};void friendclass::show(myclass &c){cout << "num = " << setw(5) <<setfill(' ') << c.num <<endl;
}
void friendclass::show(){}
int main()
{myclass c(10);(new friendclass()) ->show(c);
}
class init
num =    10
class destroy

二 友元类

除了可以声明函数为类的友元函数,还可以将一个类声明为友元类,友元类可以声明在类中任意位置。声明友元类之后,友元类中的所有成员函数都是该类的友元函数,能够访问该类的所有成员。与声明友元函数类似,友元类也是使用关键字friend声明,其语法格式如下:

在前面例子的基础上修改:

#include <iostream>
#include <iomanip>
using namespace std;class myclass;
class friendclass{
public:friendclass(){}void show();void show(myclass &c);
};
class myclass{//修改的这里
//friend void friendclass::show(myclass &c);friend class friendclass;
public:myclass(int n):num(n){cout << "class init" << endl;}~myclass(){cout << "class destroy" << endl;}void show(){cout << "num = " << setw(5) <<setfill(' ') << num <<endl;}
private:int num;
};void friendclass::show(myclass &c){cout << "num = " << setw(5) <<setfill(' ') << c.num <<endl;
}
void friendclass::show(){}
int main()
{myclass c(10);(new friendclass()) ->show(c);
}
class init
num =    10
class destroy

三 使用友元应注意的地方

从面向对象程序设计来讲,友元破坏了封装的特性。但由于友元简单易用,因此在实际开发中较为常用,如数据操作、类与类之间消息传递等,可以提高访问效率。使用友元需要注意以下几点:

①友元声明位置由程序设计者决定,且不受类中public、private、protected权限控制符的影响。

②友元关系是单向的,即类A是类B的友元,但B不是A的友元。

③友元关系不具有传递性,即类C是类D的友元,类E是类C的友元,但类E不是类D的友元。④友元关系不能被继承。

小结

C++学习1:C++友元函数和友元类相关推荐

  1. C++学习笔记(10)运算符重载,友元函数,友元类

    c++允许我们为运算符定义专门的函数,这被称为运算符重载: 运算符可以简化字符串的操作,'+',以及使用关系运算符比较字符串,[ ]运算符访问向量中的元素: 例如: #include <iost ...

  2. C++学习之友元函数和友元类

    目录 一.前言 二.友元函数 1. 介绍 2. 示例代码 三.友元类 1. 介绍 2. 示例代码 一.前言 主要介绍C++中的友元函数和友元类. 二.友元函数 1. 介绍 友元函数定义在类的外部,通过 ...

  3. c++远征之模板篇——友元函数、友元类

    以下内容源于慕课网的学习整理,如有侵权,请告知删除. 一.友元函数 1.分类 全局函数-->友元全局函数 成员函数-->友元成员函数 2.关键字friend 友元全局函数 如下,利用fri ...

  4. c语言friend函数,C++ friend友元函数和友元类

    友元函数和友元类在实际开发中较少使用,想快速学习C++的读者可以跳过本节. 一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有 ...

  5. Th3.9:友元函数、友元类、友元成员函数详述

     本博客将记录:类的相关知识点的第9节的笔记! (这个在学习C++基础课程时已经学习过一次了,这里再次简单地回顾一下而已) 今天总结的知识分为以下3个点:   一.友元函数(对于非成员函数而言)   ...

  6. C++ 笔记(30)— 友元函数与友元类

    我们知道类的私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. ...

  7. C++友元函数和友元类(C++ friend)详解

    在看VISP视觉库的时候遇到友元函数: Friends void swap (vpDetectorAprilTag &o1, vpDetectorAprilTag &o2) 在定义一个 ...

  8. 模板类中使用友元函数的方式,派生类友元函数对基类的成员使用情况

    在一般友元函数的前面加上 template<typename T),注意在函数的声明和定义处都要加这个模板 例如: //模板类,长方体类 template <typename Elemen ...

  9. c++友元函数与友元类

    友元函数和友元类的需要: 类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这 ...

最新文章

  1. 二次元老婆生成器,想要什么样的老婆就靠自己勤劳的双手啦
  2. 如何让人工智能更加实际的辅助网络安全
  3. c 语言程序设计(清华大学郑莉),C+语言程序设计(清华大学郑莉)十一ppt课件
  4. Gartner Magic Quadrant for Enterprise Network Firewall (2018,2017,2016,2015,2014,2013,2011,2010)
  5. JS之Window对象
  6. 攻防世界 WEB 新手练习区 答题(1-12题解)
  7. ftp连接530错误
  8. 基于单片机的智能照明控制系统设计
  9. blast2go windows 下本地化
  10. map、set、multimap、multiset、hash_map、hah_set、hash_multimap、hash_multiset
  11. WEB安全 TCP协议安全 应用安全 信息安全 业务安全 SDK嵌入式防护 等保 攻击溯源 CDN DCDN
  12. 一篇文章带你了解网络编程(总结)
  13. 水井硬件集成与仪表仪器采集
  14. synchronized 和 AQS
  15. o7_dictionary_accessibility 参数
  16. Android 拨打电话各安卓版本适用
  17. CSS和HTML基操
  18. Socket编程、协议理解
  19. 达人评测 酷睿i7 1195g7 和奔腾n6000选哪个
  20. 无线充电的技术原理和发展现状

热门文章

  1. 印刷机械行业设备远程监控及故障预警诊断系统
  2. 腾讯QQ“兴趣部落”将停止运营
  3. java控制网页_教你用纯Java实现一个网页版的Xshell(附源码)
  4. Java进阶(十三)网络编程
  5. python转码方法_python转码问题
  6. AE中将图层作为蒙版使用
  7. JAVA手写算法 | 冒泡排序算法
  8. CentOS 7最小化安装后的必备操作
  9. 获取apk证书MD5值的方法
  10. android应用获取通知栏权限