28,友元的尴尬能力

1. 友元的概念

(1)友元C++中的一种关系

(2)友元关系发生在函数与类之间或类与类之间

(3)友元关系是单项的不能传递

复制代码
class Point
{
    double x;
    double y;
    friend void func(Point& p);  //声明func为Point类的友元函数-----将Point类和全局函数finc()联系起来,----使得func()具有的超能力,可以访问Point全部成员
} 

void func(Point& p){};     //全局函数,参数是类的引用,接受一个Ponit对象作为参数---------可以访问Point类内的任何成员!
复制代码

2. 友元的用法

(1)在类中以friend关键字声明友元

(2)类的友元可以是其它类或者具体函数

(3)友元不是类的一部分,也不受类中访问级别的限制,可以直接访问具体类的所有成员--------超能力

(4)用友元注意事项

  ①友元关系不具备传递性

       

  ②类的友元可以是其它类的成员函数(即其它类的成员函数作为该类的友元函数

  ③类的友元可以是某个完整的类(即所有的成员函数都是友元

 1 #include <stdio.h>
 2 #include <math.h>
 3 
 4 class Point
 5 {
 6 private:
 7 
 8     double x;
 9     double y;
10 
11 public:
12 
13     Point(double x, double y)
14     {
15         this->x = x;
16         this->y = y;
17     }
18 
19     double getX(){return x;}
20     double getY(){return y;}
21 
22     void getXY()
23     {
24         printf("x = %f, y = %f\n", x, y);
25     }
26 
27    friend double Distance(Point& p1, Point& p2);  //Distance是point的友元,Distance可以访问类的一切成员,main不可以
28 
29 };
30 
31 
32 
33 double Distance(Point& p1, Point& p2)
34 {
35      double ret = 0;
36 
37      //ret=sqrt((p2.x-p1.x)*(p2.x-p1.x) +
38 
39               (p2.y-p1.y)*(p2.y-p1.y));     //error-----------Distance全局函数与point没有关系,Distance是类的外部,当然不能引用类中的私有成员!
40     //上面改写成
41      ret = (p2.getY()- p1.getY()) * (p2.getY() - p1.getY()) +
42            (p2.getX() - p2.getX()) * (p2.getX() - p1.getX());    //调用8次函数,效率低,---引入友元解决
43 
44      //引入友元
45      ret = (p2.y()- p1.y()) * (p2.y() - p1.y()) +
46            (p2.x() - p2.x()) * (p2.x() - p1.x());
47 
48      ret=sqrt(ret);
49 
50      return ret;
51 
52 }
53 
54 int main()
55 {
56     Point p1(1, 2);
57 
58     Point p2(10, 20);
59 
60     p1.getXY();
61 
62     p2.getXY();
63 
64     printf("p1(%f,%f)\n", p1.getX(), p1.getY());          //mian 和Point
65     printf("p2(%f,%f)\n", p2.getX(), p2.getY());
66     printf("|(p1,p2)|=%f\n", Distance(p1, p2));
67 
68     return 0;
69 
70 }

3. 友元的尴尬

(1)友元为了兼顾C语言的高效而诞生的,但直接破坏面向对象的封装性(每个类豆子间谍私有成员,不能被外界访问)c++当作c语言,不符合初心

(2)友元在实际产品中的高效是得不偿失的在现代软件工程中己经逐渐被遗弃

【编程实验】友元的深入分析

 1 #include<stdio.h>  
 2 
 3 //类与类之间也有友元关系,但是没有传递性
 4 //破坏了对象的封装性,如:不能随便访问类的私有成员
 5 
 6 class Classc
 7 {
 8     const char* n;      //字符指针,n表示类对象的名字
 9 public:
10     Classc(const char* n)
11     {
12         this->n = n;
13     }
14 
15     friend class Classb;        //友元,b可以访问c的私有成员
16 };
17 
18 class Classb
19 {
20     const char* n;             //字符指针,n表示类对象的名字
21 public:
22     Classb(const char* n)
23     {
24         this->n = n;
25     }
26 
27     //访问c的名字
28     void getClassName(Classc& c)
29     {
30         printf("c.n=%s\n", c, n);
31     }
32 
33     friend class Classa;            //友元,a可以访问b的私有成员
34 };
35 
36 class Classa
37 {
38     const char* n;                  //字符指针,n表示类对象的名字
39 public:
40     Classa(const char* n)
41     {
42         this->n = n;
43     }
44 
45     //访问b的名字
46     void getClassName(Classb& b)
47     {
48         printf("b.n=%s\n", b, n);
49     }
50 
51 };
52 
53 
54 int main()
55 {
56     //A是B的友元类,B是C的友元类,但A不能自动传递为C的友元类
57 
58     Classa A("O");
59     Classb B("P");
60     Classc C("Q");
61 
62     A.getClassName(B);  //B
63     B.getClassName(C);  //c
64 
65 
66     return 0;
67 }

4. 小结

(1)友元是为了兼顾C语言的高效而诞生的

(2)友元直接破坏了面向对象的封装性

(3)友元关系不具备传递性

(4)类的友元可以是其它类的成员函数

(5)类的友元可以是某个完整的类

猜你喜欢

转载自www.cnblogs.com/liuyueyue/p/13376981.html