为什么使用友元?
例如:求两点之间的距离
#include <iostream>
#include <cmath>
class Point //Point类声明
{
public: //外部接口
Point(int x=0, int y=0) : x(x), y(y) { }
int getX()
{
return x;
}
int getY()
{
return y;
}
private: //私有数据成员
int x, y;
};
float dist( Point& a, Point& b)
{
double x = a.getX() - b.getX();
double y = a.getY() - b.getY();
return static_cast<float>(sqrt(x * x + y * y));
}
解决方法:设计一个函数计算两点间的距离,解决方案普通函数,成员函数和类的组合都不好,最好采用友元关系。
友元
面向对象程序设计主张程序的封装、数据的隐藏,不过任何事物都不是绝对的,友元打破了这种封装和隐藏。
友元关系提供了一种共享机制,实现不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享。
通俗点举个例子,一个家庭需要通过防盗门窗、门锁、保险柜等措施不让外人接触,但在一些特殊情况下,例如全家出游,又需要检查煤气、水电情况,就不得不把钥匙交给值得依赖的朋友,而这位朋友就是友元。
即通过友元关系,一个普通函数或者类的成员函数可以访问封装于另外一个类的数据。
同时也要明白,友元是C++提供的一种破坏数据封装和数据隐藏的机制。便于实现数据共享,提高程序的效率和可读性。
为了确保数据的完整性及数据封装与隐藏的原则,建议尽量不使用或少使用友元。
在一个类中,可以利用关键字 friend将其他函数或类声明为友元。可以使用友元函数和友元类。
友元函数
如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为本类的友元函数。友元函数可以访问这个类中的私有成员和受保护成员。
作用:增加灵活性,使程序员可以在封装和快速性方面做合理选择。
访问对象中的成员必须通过对象名。
UML中由关键字friend修饰。
#include <iostream>
#include <cmath>
class Point //Point类声明
{
public: //外部接口
Point(int x=0, int y=0) : x(x), y(y) { }
int getX()
{
return x;
}
int getY()
{
return y;
}
friend float dist(Point &a, Point &b);
private: //私有数据成员
int x, y;
};
float dist( Point& a, Point& b)
{
double x = a.x - b.x;
double y = a.y - b.y;
return static_cast<float>(sqrt(x * x + y * y));
}
int main()
{
Point p1(1, 1), p2(4, 5);
cout <<"The distance is: ";
cout << dist(p1, p2) << endl;
return 0;
}
友元类
不仅可以将一个函数声明为一个类的“朋友”,而且可以将一个类(例如B类)声明为另一个类(例如A类)的“朋友”。这时B类就是A类的友元类。友元类B中的所有函数都是A类的友元函数,可以访问A类中的所有成员。
在A类的定义体中用以下语句声明B类为其友元类:friend B;
声明友元类的一般形式为:
friend 类名;
友元类之间的关系不能传递,不能继承。友元的关系是单向的而不是双向的。进行函数重载时,需要将重载函数集中每一个希望设为友元的函数都声明为友元。
class A
{
friend class B;
public:
void display()
{
cout << x << endl;
}
private:
int x;
}
class B
{
public:
void set(int i);
void display();
private:
A a;
};
void B::set(int i)
{
a.x=i;
}
void B::display()
{
a.display();
}
来源:https://www.cnblogs.com/wkfvawl/p/10801928.html