友元相关

 

友元的定义:友元可以是一个函数,该函数被称为友元函数;友元也可以是一个,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend

友元函数的定义:类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

 

   下面首先举一个例子来说明友元函数的应用:

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 class Point   //定义一个Point类
 5 {
 6 public:
 7     Point(double xx, double yy)
 8     {
 9         x = xx;
10         y = yy;
11     };
12     void Getxy();
13     friend double Distance(Point &a, Point &b);  //将函数Distance定义为Point类的友元函数
14 private:
15     double x, y;
16 };
17 void Point::Getxy()       //对Point类中的Getxy函数进行定义
18 {
19     cout << "(" << x << "," << y << ")" << endl;  //输出该点的x,y值
20 }
21 double Distance(Point &a, Point &b)  //定义Distance函数
22 {
23     double dx = a.x - b.x;
24     double dy = a.y - b.y;
25     return sqrt(dx*dx + dy*dy);
26 }
27 int main(void)
28 {
29     Point p1(3.0, 4.0), p2(6.0, 8.0);  //定义并初始化两个点p1,p2
30     p1.Getxy();
31     p2.Getxy();
32     double d = Distance(p1, p2);      //计算两点之间的距离
33     cout << "Distance is" << d << endl;
34     return 0;
35 }

 

在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加friend关键字,标识它不是成员函数,而是友元函数。它的定义方法与普通函数定义一样,而不同于成员函数的定义,因为它不需要指出所属的类。但是,它可以引用类中的私有成员,函数体中a.x,b.x,a.y,b.y都是类的私有成员,它们是通过对象引用的。在调用友元函数时,也是同普通函数的调用一样,不要像成员函数那样调用。本例中,p1.Getxy()和p2.Getxy()这是成员函数的调用,要用对象来表示。而Distance(p1, p2)是友元函数的调用,它直接调用,不需要对象表示,它的参数是对象。(该程序的功能是已知两点坐标,求出两点的距离。)

 

代码运行结果如下:

 

友元除了函数以外,还可以是类,即一个类可以作另一个类的友元。当一个类作为另一个类的友元时,这就意味着这个类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。需要注意,只有当一个类的定义已经被定义时,它的成员函数才能被声明为另一个类的友元。
定义友元类的语句格式如下:
 
  friend class 类名(即友元类的类名);
 
 
 
下面我们再来看一个例子,要求分别定义一个类A和类B ,各有一个私有整数成员变量通过构造函数初始化;类A有一个成员函数Show(B &b)用来打印A和B的私有成员变量,请分别通过友元函数和友元类来实现此功能。使用友元类 和 友元函数实现
 
 1 #include <iostream>
 2 using namespace std;
 3 
 4 
 5 class B;  //定义类B
 6 class A;  //定义类A
 7 
 8 void Show(A&, B&);
 9 
10 class B
11 {
12 private:
13     int tt;
14     friend class A;   //将A类声明为B类的友元
15     friend void Show(A&, B&);   //将函数Show定义为B类的友元函数
16 public:
17     B(int temp = 100) :tt(temp) {}
18 };
19 
20 class A
21 {
22 private:
23     int value;
24     friend void Show(A&, B&);   //将函数Show定义为A类的友元函数
25 public:
26     A(int temp = 200) :value(temp) {}
27     void Show(B& b)
28     {
29         cout << value << endl;
30         cout << b.tt << endl;
31     }
32 };
33 
34 
35 void Show(A& a, B& b)   //定义友元函数Show
36 {
37     cout << a.value << endl;
38     cout << b.tt << endl;
39 }
40 
41 int main()
42 {
43     A a;
44     B b;
45     a.Show(b);
46     Show(a, b);
47     return 0;
48 }

 

 

 

代码运行结果如下:

 

 

 需要注意:

1)必须在类的说明中说明友元函数,说明时以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在private和public部分;

2)注意友元函数不是类的成员函数,所以友元函数的实现和普通函数一样,在实现时不用"::"指示属于哪个类,只有成员函数才使用"::"作用域符号;

3)友元函数不能直接访问类的成员,只能访问对象成员,

4)友元函数可以访问对象的私有成员,但普通函数不行;

5)调用友元函数时,在实际参数中需要指出要访问的对象,

6)类与类之间的友元关系不能继承。

posted @ 2019-09-25 22:09  slanxer  阅读(167)  评论(0编辑  收藏  举报