C++基础10-类和对象之友元函数
采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员, 这时可以将这些函数定义为该 函数的友元函数。除了友元函数外,还有友元类, 两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和 安全性检查等都需要时间开销),但它破坏了类的封装 性和隐藏性,使得非成员函数可以访问类的私有成员。 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元 类。
友元函数没有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-类和对象之友元函数相关推荐
- 深入篇【C++】类与对象:友元函数与友元类
深入篇[C++]类与对象:友元函数与友元类 ①.提出问题:重载operator<< ②.解决问题:友元 Ⅰ.友元函数 [特点] Ⅱ.友元类 [特点] ③.总结问题 ①.提出问题:重载ope ...
- 3-8:类与对象下篇——友元函数、友元类和内部类
文章目录 一:友元函数 (1)友元函数 (2)友元类 二:内部类 一:友元函数 C++运算符重载为我们带来了极大的便利.因此,对于日期类这样的自定义类型,就可以重载运算符<<,然后使用co ...
- 【C++基础】类和对象——友元
[C++基础]类和对象--友元 友元的概念 在C++中,不能被外部访问的私有属性,通过友元可以访问. 友元的关键字:friend 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 一.全局函数 ...
- JAVA基础七 类和对象
文章目录 JAVA基础七 类和对象 01 引用 02 继承 03 方法重载 04 构造方法 05 this 06 传参 07 包 08 访问修饰符 09 类属性 10 类方法 11 属性初始化 12 ...
- JAVA基础––从类和对象开始
JAVA基础--从类和对象开始 一.概念 1.面向对象中类和对象的概念 对象:对象是具有状态和行为的实体,例如某个具体的学生,或者是王者荣耀里的英雄,可以是物理实体,也可以是逻辑实体. 类:类是一组具 ...
- Java_面向对象基础(类、对象、方法和构造函数)
Java的面向对象基础(类.对象.方法和构造函数) 面向对象的基本概念 面向对象的设计思想 什么是类 什么是对象 类的定义 设计面向对象的例子 步骤一:设计动物这个类 步骤二:创建具体的动物 步骤三: ...
- C++类和对象:友元
C++类和对象:友元 本文是笔者在C++学习过程中,对类和对象的总结记录,如有不对以及不足的地方,欢迎大家指正! 在C++当中,由于类内权限的限制,使得类内成员得到了隐藏:在类外访问不到类的私有属 ...
- java基础(类与对象、集合)
java基础(类与对象.集合) 类与对象 类与对象中的栈和堆 构造方法 this关键字 面向对象三大特性 封装性(private) 继承性(extends) 方法重写(@override) 多态性 向 ...
- 当类模板遇到了友元函数
在我学习数据结构的时候,选用了<数据结构(用面向对象方法与C++语言描述)>殷人昆 编著 这本教材.这本书代码较老有一些错误,好多是无法直接在新版本编译器下实现的. 当时我C++模板学的不 ...
最新文章
- snapd_snapd使管理Nextcloud变得轻而易举
- java异常_Java的异常体系
- 正则表达式发明者_正则表达式 – 简介
- IO:select、poll、epoll
- python字典序列化是什么意思_如何将Python字典序列化为字符串,然后回到字典?...
- html导航去下划线,纯CSS实现导航栏下划线跟随的示例代码
- MySQL 的覆盖索引与回表
- android系统耗电量大待机,安卓手机耗电快有什么解决办法吗 安卓手机待机耗电量大怎么办...
- Javascript三种创建对象的方法,new关键字,for...in 遍历对象
- js添加option设置空值_3.11 在散点图中添加标签(2)
- OBS 录制简单操作说明
- linux趋势杀毒安装目录,趋势杀毒软件在AX3.0上的安装
- 阿拉伯数字与中文大写转换excel公式
- PyTorch源码解读之torchvision.models
- HiveSQL最近7/30日各品牌复购率
- 线下餐饮实体店线上精准引流方案!你想看的都在这儿!这篇文章教你转化!
- ICCV2021 | Vision Transformer中相对位置编码的反思与改进
- ck6.8整合php,WordPress整合ckplayer X和ckplayer 6.8的最新完美代码
- android监听服务,服务监听打电话
- 什么是计算机视觉,主要有哪些应用?
热门文章
- Java数据库篇6——多表查询
- matlab fgetl用法,Matlab fgetl strsplit 函数
- 自动设置图片的序号_编写学位论文时如何给表格和图片自动编号
- c++调用python接口作用是_利用Boost::Python实现C++调用python接口
- python3自动化软件发布系统_基于python3做C/S端自动化测试可能用到的工具(不断更新中。。。。)...
- js 原型以及原型链
- xp系统怎样添加桌面计算机名,教你win10系统电脑桌面怎么添加日历
- 方正高影仪安装方法_铝合金门窗是怎么安装的?
- java面试题_1000道Java工程师面试题+答案PDF485页
- mysql 回滚之后抛出异常_在PHP中 开始事务后,程序抛出异常 没有执行commit也没有执行rollback mysql事务会回滚吗?...