C++友元函数与友元类
允许特定的函数访问一个类的私有成员,一般直接在类中直接声明函数就能简单做到。但需要允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问就需要友元(friend)函数来解决。
一,概念提出:什么是友元?
友元(friend)机制允许一个类将对其非公有成员的访问权授予指定的函数或者类,友元的声明以friend开始,它只能出现在类定义的内部,友元声明可以出现在类中的任何地方:友元不是授予友元关系的那个类的成员,所以它们不受其声明出现部分的访问控制影响。通常,将友元声明成组地放在类定义的开始或结尾是个好的方法。
二,使用方法:如何使用友元?
下面我们在两方面介绍友元机制的使用
友元函数 :
友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:
1 friend 类型 函数名(形式参数);
友元类 :
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
1 friend class 类名;
三,实验与验证:如何运用友元?
下面我们通过一个简单的实验来探讨友元函数的用法
例子:首先定义一个点类(Point) , 现在如何求两点之间的距离?
代码如下:
1 #include<iostream> 2 #include<math.h> 3 4 using namespace std; 5 class Point { 6 public:Point(int x = 0, int y = 0) : x(x), y(y) {}//构造函数 7 friend double Pointdistance(Point &a, Point &b);//声明友元函数 8 private: 9 int x, y; 10 11 }; 12 13 double Pointdistance(Point &a,Point &b) { 14 double dis; 15 dis = sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); 16 //直接访问Point类的private成员 17 return dis; 18 } 19 20 21 int main() 22 { 23 Point a(4,5); 24 Point b(1,1); 25 cout << Pointdistance(a, b); 26 return 0; 27 }
运行结果:
友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。
一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
友元函数的调用与一般函数的调用方式和原理一致。
下面我们通过一个简单的实验来探讨友元类的用法
例子:设计一个程序老师(类)通过类的友元修改学生(类)的私有数据
代码如下:
1 #include <iostream> 2 #include<string> 3 using namespace std; 4 5 class Student 6 { 7 public: 8 Student() 9 { 10 id = "unknown"; 11 name = "unknown"; 12 } 13 void Init_info() 14 { 15 string id_temp; 16 string name_temp; 17 cout << "Please Enter Student‘s id: "; 18 cin >> id_temp; 19 cout << "Please Enter Student‘s Name: "; 20 cin >> name_temp; 21 id = id_temp; 22 name = name_temp; 23 } 24 void Print_info() 25 { 26 cout << "Name:" << name << endl; 27 cout << "id:" << id << endl; 28 } 29 friend class Teacher; 30 private: 31 string id, name; 32 }; 33 34 class Teacher 35 { 36 public: 37 38 void Change_Stu_info() 39 { 40 string newid; 41 string newname; 42 cout << "请输入新ID:"<<endl; 43 cin >> newid; 44 cout << "请输入新NAME:"<<endl; 45 cin >> newname; 46 S.id = newid;//直接修改学生(类)的私有成员 47 S.name = newname;; 48 } 49 void Check_Stu_info() 50 { 51 S.Print_info();//通过友元执行学生(类)的函数 52 } 53 private: 54 Student S; 55 }; 56 57 int main() 58 { 59 Student S1; 60 Teacher T1; 61 cout << "修改前:" << endl; 62 S1.Print_info(); 63 T1.Change_Stu_info();//老师修改学生的数据 64 cout << "修改后:" << endl; 65 T1.Check_Stu_info(); 66 return 0; 67 }
运行结果:
friend和class是关键字,类名必须是程序中的一个已定义过的类。
友元关系不可传递,不能继承,是单向的。
友元类是为了访问类的私有和保护成员。
使类B中的成员函数成为类A的友元函数,这样类B的该成员函数就可以访问类A的所有成员。
四,友元的缺点
类本身的就有封装的作用,而友元的作用正好相反,类将对其非公有成员的访问权限授予其他函数或者类,会破坏该类的封装性,降低该类的可靠性和可维护性。