C++基础10-类和对象之友元函数

25 篇文章 1 订阅
22 篇文章 2 订阅

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

友元函数没有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);  //写在哪个位置都ok
	friend double PointManager::PointDistance3(Point &p1, Point &p2);  //写在哪个位置都ok
	Point(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 的友元,同样要看类中是否有相应的声明。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chde2Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值