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

友元函数没有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. snapd_snapd使管理Nextcloud变得轻而易举
  2. java异常_Java的异常体系
  3. 正则表达式发明者_正则表达式 – 简介
  4. IO:select、poll、epoll
  5. python字典序列化是什么意思_如何将Python字典序列化为字符串,然后回到字典?...
  6. html导航去下划线,纯CSS实现导航栏下划线跟随的示例代码
  7. MySQL 的覆盖索引与回表
  8. android系统耗电量大待机,安卓手机耗电快有什么解决办法吗 安卓手机待机耗电量大怎么办...
  9. Javascript三种创建对象的方法,new关键字,for...in 遍历对象
  10. js添加option设置空值_3.11 在散点图中添加标签(2)
  11. OBS 录制简单操作说明
  12. linux趋势杀毒安装目录,趋势杀毒软件在AX3.0上的安装
  13. 阿拉伯数字与中文大写转换excel公式
  14. PyTorch源码解读之torchvision.models
  15. HiveSQL最近7/30日各品牌复购率
  16. 线下餐饮实体店线上精准引流方案!你想看的都在这儿!这篇文章教你转化!
  17. ICCV2021 | Vision Transformer中相对位置编码的反思与改进
  18. ck6.8整合php,WordPress整合ckplayer X和ckplayer 6.8的最新完美代码
  19. android监听服务,服务监听打电话
  20. 什么是计算机视觉,主要有哪些应用?

热门文章

  1. Java数据库篇6——多表查询
  2. matlab fgetl用法,Matlab fgetl strsplit 函数
  3. 自动设置图片的序号_编写学位论文时如何给表格和图片自动编号
  4. c++调用python接口作用是_利用Boost::Python实现C++调用python接口
  5. python3自动化软件发布系统_基于python3做C/S端自动化测试可能用到的工具(不断更新中。。。。)...
  6. js 原型以及原型链
  7. xp系统怎样添加桌面计算机名,教你win10系统电脑桌面怎么添加日历
  8. 方正高影仪安装方法_铝合金门窗是怎么安装的?
  9. java面试题_1000道Java工程师面试题+答案PDF485页
  10. mysql 回滚之后抛出异常_在PHP中 开始事务后,程序抛出异常 没有执行commit也没有执行rollback mysql事务会回滚吗?...