如果类外部有一个函数经常访问该类的成员变量(private),那么可以在类内加上friend关键字,将类外的函数声明为该类的友元函数,那么可以在友元函数里直接访问类的成员变量(而不需要通过get、set方法)。
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
class Point
{
public:
Point(int x, int y):m_X(x),m_Y(y)
{
}
int getX()
{
return m_X;
}
int getY()
{
return m_Y;
}
friend double PointDistance(Point &p1, Point &p2);
private:
int m_X;
int m_Y;
};
double PointDistance(Point &p1, Point &p2)
{
//常规使用get方法,但如果PointDistance经常调用,则会有较多的入站出站操作,需要时间开销
//int dd_x = p1.getX()-p2.getX();
//int dd_y = p1.getY()-p2.getY();
//将函数定义为友元类之后,可以直接访问类的私有变量
int dd_x = p1.m_X-p2.m_X;
int dd_y = p1.m_Y-p2.m_Y;
double dis = sqrt(dd_x*dd_x + dd_y*dd_y);
return dis;
}
int main(void)
{
Point a(1, 1);
Point b(2, 2);
cout<<"a and b dis="<<PointDistance(a, b)<<endl;
return 0;
}
采用类的机制后实现了数据的隐藏和封装,类的数据成员一般都会定义为私有成员,成员函数一般定义为公有的,依次提供类与外界的通讯接口。
但是有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁的访问类的数据成员,这时可以讲这些函数定义为该类的友元函数。除了友元函数,还有友元类,两者统称为友元。
友元的作用是提高了程序的运行效率(减少类型检查和安全性检查都需要时间开销,值拷贝操作),但是它破坏了类的封装性和隐蔽性,使得非成员函数可以访问类的私有成员。
注意:
(1)、友元关系不能继承
(2)、友元关系是单向的,不具有交换性。若B是类A的友元,类A不一定是类B的友元。(我把你当做好朋友,你却不一定把我当做好朋友,好伤心...呜呜呜...)
(3)、友元关系不具有传递性。类B是类A的友元,类C是类B的友元,但类C不一定是类A的友元。(朋友的朋友,不一定是朋友,可能还是敌人...)