C++友元函数与友元类

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的所有成员。

四,友元的缺点

类本身的就有封装的作用,而友元的作用正好相反,类将对其非公有成员的访问权限授予其他函数或者类,会破坏该类的封装性,降低该类的可靠性和可维护性。

 

posted @ 2019-09-29 23:57  LGboy  阅读(321)  评论(0编辑  收藏  举报