采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员, 这时可以将这些函数定义为该 函数的友元函数。除了友元函数外,还有友元类, 两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和 安全性检查等都需要时间开销),但它破坏了类的封装 性和隐藏性,使得非成员函数可以访问类的私有成员。 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元 类。

友元函数没有this指针。this指针是在指向类成员本身,但是友元函数并不在类里面,而是在类外面

1、友元函数

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

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

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

2、友元类

#if 1
#include<iostream>
#include<math.h>
using namespace std;class Point;
class PointManager {
public:double PointDistance3(Point &p1, Point &p2);
};class Point {
public://声明全局函数 PointDistance2 是我类Point的一个友元函数friend double PointDistance2(Point &p1, Point &p2);  //写在哪个位置都okfriend double PointManager::PointDistance3(Point &p1, Point &p2);  //写在哪个位置都okPoint(int x, int y) {this->m_x = x;this->m_y = y;
}int get_x() {return m_x;}int get_y() {return m_y;}private:int m_x;int m_y;};
double PointDistance1(Point &p1, Point &p2) {double dis;//int dd_x = p1.m_x - p2.m_x;  编译错误int dd_x = p1.get_x() - p2.get_x();int dd_y = p1.get_y() - p2.get_y();dis = sqrt(dd_x*dd_x + dd_y*dd_y);return dis;
}
double PointDistance2(Point &p1, Point &p2) {  //声明为友元函数double dis;int dd_x = p1.m_x - p2.m_x;int dd_y = p1.m_y - p2.m_y;dis = sqrt(dd_x*dd_x + dd_y*dd_y);return dis;
}
# if 0
//此种写法错误
//改为友元函数类内申明 类外实现
class PointManager {
public:double PointDistance3(Point &p1, Point &p2) {double dis;int dd_x = p1.m_x - p2.m_x;int dd_y = p1.m_y - p2.m_y;dis = sqrt(dd_x*dd_x + dd_y*dd_y);return dis;}
};
#endif//类中友元函数
double PointManager::PointDistance3(Point &p1, Point &p2) {double dis;int dd_x = p1.m_x - p2.m_x;int dd_y = p1.m_y - p2.m_y;dis = sqrt(dd_x*dd_x + dd_y*dd_y);return dis;
}void test01() {Point p1(1, 2), p2(2, 2);int dis = PointDistance1(p1, p2);cout << "dis:" << dis << endl;    //dis:1
}void test02() {Point p1(1, 2), p2(2, 2);PointManager pm;cout << pm.PointDistance3(p1, p2) << endl;  //1
}
int main(void) {//test01();test02();return 0;
}
#endif

3、论友元

声明位置:

友元声明以关键字 friend 开始,它只能出现在类定义中。因为友元不是授权类的成员,所以它不受其所在类的声明区域 public private 和 protected 的影 响。通常我们选择把所有友元声明组织在一起并放在类头之后.

友元的利弊:

友元不是类成员,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问 类的私有成员。 不过,类的访问权限确实在某些应用场合显得有些呆板,从而容 忍了友元这一特别语法 现象。

注意事项:

(1) 友元关系不能被继承。

(2) 友元关系是单向的,不具有交换性。若类 B 是类 A 的友元,类 A 不一定是类B 的友元,要看在类中是否有相应的声明。

(3) 友元关系不具有传递性。若类 B 是类 A 的友元,类 C 是 B 的友元,类 C 不一定 是类 A 的友元,同样要看类中是否有相应的声明。

C++基础10-类和对象之友元函数相关推荐

  1. 深入篇【C++】类与对象:友元函数与友元类

    深入篇[C++]类与对象:友元函数与友元类 ①.提出问题:重载operator<< ②.解决问题:友元 Ⅰ.友元函数 [特点] Ⅱ.友元类 [特点] ③.总结问题 ①.提出问题:重载ope ...

  2. 3-8:类与对象下篇——友元函数、友元类和内部类

    文章目录 一:友元函数 (1)友元函数 (2)友元类 二:内部类 一:友元函数 C++运算符重载为我们带来了极大的便利.因此,对于日期类这样的自定义类型,就可以重载运算符<<,然后使用co ...

  3. 【C++基础】类和对象——友元

    [C++基础]类和对象--友元 友元的概念 在C++中,不能被外部访问的私有属性,通过友元可以访问. 友元的关键字:friend 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 一.全局函数 ...

  4. JAVA基础七 类和对象

    文章目录 JAVA基础七 类和对象 01 引用 02 继承 03 方法重载 04 构造方法 05 this 06 传参 07 包 08 访问修饰符 09 类属性 10 类方法 11 属性初始化 12 ...

  5. JAVA基础––从类和对象开始

    JAVA基础--从类和对象开始 一.概念 1.面向对象中类和对象的概念 对象:对象是具有状态和行为的实体,例如某个具体的学生,或者是王者荣耀里的英雄,可以是物理实体,也可以是逻辑实体. 类:类是一组具 ...

  6. Java_面向对象基础(类、对象、方法和构造函数)

    Java的面向对象基础(类.对象.方法和构造函数) 面向对象的基本概念 面向对象的设计思想 什么是类 什么是对象 类的定义 设计面向对象的例子 步骤一:设计动物这个类 步骤二:创建具体的动物 步骤三: ...

  7. C++类和对象:友元

    C++类和对象:友元 本文是笔者在C++学习过程中,对类和对象的总结记录,如有不对以及不足的地方,欢迎大家指正!   在C++当中,由于类内权限的限制,使得类内成员得到了隐藏:在类外访问不到类的私有属 ...

  8. java基础(类与对象、集合)

    java基础(类与对象.集合) 类与对象 类与对象中的栈和堆 构造方法 this关键字 面向对象三大特性 封装性(private) 继承性(extends) 方法重写(@override) 多态性 向 ...

  9. 当类模板遇到了友元函数

    在我学习数据结构的时候,选用了<数据结构(用面向对象方法与C++语言描述)>殷人昆 编著 这本教材.这本书代码较老有一些错误,好多是无法直接在新版本编译器下实现的. 当时我C++模板学的不 ...

最新文章

  1. tftp:timeout问题解决 - 从Windows传输文件到开发板
  2. string去掉后四位_数字黑洞(下):四位数的黑洞
  3. MyBatis整合ehcache实现二级缓存
  4. 10th blog:Object
  5. IE10,IE9透明元素无法点击
  6. android标签打印,Android TSC热敏标签打印机打印
  7. 这几个概念你可能还是没搞清require、import和export
  8. 如何在 Mac 上设置图片或视频的默认打开应用?
  9. BaseAdapter使用的三种形式,逗比式,普通式,文艺式
  10. WIN7英文语言包下载,安装,使用
  11. java md5在线解密免费_Java MD5如何解密?
  12. SMT贴片加工回流焊接出现的问题和解决对策
  13. linux 搜狗输入法快捷键设置,Linux配置中文输入法(搜狗输入法)-Go语言中文社区...
  14. UPC6615: Snuke Festival
  15. 【云计算】一文了解裸金属服务器(一)
  16. 本地搭建我的世界服务器(可联机)
  17. angular ngOnInit 与constructor
  18. 即将公布的2020年10m分辨率全球土地利用数据(欧空局出品)
  19. AE开发中“无法嵌入互操作类型*****,请改用适用的接口”解决办法
  20. postgresql 服务器日志

热门文章

  1. oracle数据库日期加一,日期和Oracle数据库
  2. mybatis可以生成不重复的id吗_Mybatis面试题吐血总结
  3. android原生调用nextjs方法,详解使用Next.js构建服务端渲染应用
  4. oracle 分区字符转换,Oracle 普通表与分区表转换
  5. python协成_Python协程(上)
  6. Java面试日常总结大杂烩
  7. JavaScript新手入门教程大全~~~
  8. 怎么加载文件_Java虚拟机从入门到入土之JVM的类加载机制
  9. python人脸识别程序如何嵌入到app_只用Python就能写安卓,简单几步实现人脸识别的App...
  10. HTML+CSS+JS实现 ❤️520爱心背景表白网页动画特效❤️