2.7、C++友元的使用
-
友元有友元函数和友元类。
-
友元的存在是为了可以不通过调用成员函数就可以直接访问类的私有数据,以提高程序运行效率。
-
友元其实是破坏了类的封装性。
-
友元的关键字:friend。
2.7.1、友元函数
- 在类体内说明,在函数的类型说明符前加关键字friend;
- 在类体外定义,定义格式与普通函数相同;
- 友元函数不是成员函数;
- 友元函数可以直接访问类体内的私有成员。
- 友元函数的说名:friend double my_distance(Point a, Point b);
//友元函数的例子
#include <iostream>
#include <math.h>
using namespace std;
class Point
{
public:
Point(double i, double j)
{
x = i;
y = j;
}
void getxy()
{
cout<<"("<<x<<","<<y<<")"<<endl;
}
friend double my_distance(const Point &a, const Point &b); //友元函数的说明
private:
double x;
double y;
};
double my_distance(const Point &a, const Point &b) //友元函数的定义
{
double dx=a.x-b.x;
double dy=a.y-b.y;
return sqrt(dx*dx+dy*dy);
}
int main()
{
double d11=3.0,d12=4.0,d21=6.0,d22=8.0;
Point p1(d11,d12);
Point p2(d21,d22);
p1.getxy();
p2.getxy();
double d = my_distance(p1,p2); //友元函数的调用
cout<<"Distance is "<<d<<endl;
return 0;
}
2.7.2、友元类
-
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
-
定义友元类的语句格式如下:
friend class 类名(即友元类的类名);
其中:friend和class是关键字。 -
当说明一个类A为另一个类B的友元时,友元类A中的所有成员函数都是另一个类B的友元函数。
//友元类的例子 #include <iostream> using namespace std; class X { public: friend class Y; //类Y 是类X 的友元类 void set(int i, int j) { x = i; y = j; } void display() { cout << "x=" << x << "," << "y=" << y << endl; } private: int x; int y; }; class Y { public: Y(int i,int j); void display(); private: X a; //数据成员为类X的子对象 }; Y::Y(int i,int j) { a.x = i; a.y = j; } void Y::display() { cout << "x=" << a.x << "," << "y=" << a.y << endl; } int main() { // X b; // b.set(5,6); // b.display(); Y c(6,9); c.display(); // b.display(); return 0; }
2.7.3、友元的注意点
- 友元的作用主要是为了提高程序的运行效率和方便编程。但随着硬件性能的提高,友元的作用也不明显,相反,友元破坏了类的封装性,所以在使用时,应权衡利弊。
- 友元关系不能被继承。
- 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
- 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。
- 友元目前主要用在操作符重载那里。