C++中的友元

1,友元的超能力在初始的时候能力很好、很实用,但是随着软件工程的发展,大家 越来越觉得友元的超能力是那么的不够友好,于是在实际的开发中,友元的超  能力就被遗弃了;

 

2,友元的概念:

 

    1,友元是 C++ 中的一种关系;

       1,这种关系发生在两个实体之间;

    2,友元关系发生在函数与类之间或者类与类之间;

    3,友元关系时单向的,不能传递;

 

3,友元的解析:

    1,在类中以 frined 关键字声明友元;

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

    3,友元不是类的一部分;

    4,友元不受类中访问级别的限制;

    5,友元可以直接访问具体类的所有成员;

       1,这就是友元的超能力;

   

4,友元的语法:

    1,在类中用 friend 关键字对函数或类进行声明;

    2,代码示例:

 1 class Point
 2 {
 3     double x;  // 私有;
 4     double y;  // 私有;
 5     
 6     friend void func(Point& p);  // func() 全局函数是 Point 类的友元,func() 可以访问 Point 类的所有成员,但是 func() 不是 Point 的成员函数;
 7 };
 8 
 9 void func(Point& p)
10 {
11 }

5,友元的使用初探编程实验:

    1,main.cpp 文件:

 1 #include <stdio.h>
 2 #include <math.h>
 3 
 4 class Point
 5 {
 6     double x;
 7     double y;
 8 public:
 9     Point(double x, double y)
10     {
11         this->x = x;  // 成员函数有一个 this 指针,用于指向当前对象;
12         this->y = y;  // 将参数 y 赋值给当前对象的 y 成员;
13     }
14     
15     double getX()
16     {
17         return x;
18     }
19     
20     double getY()
21     {
22         return y;
23     }
24        
25     friend double func(Point& p1, Point& p2);
26 };
27 
28 bouble func(Point& p1, Point& p2)
29 {
30     double ret = 0;
31 
32 /*
33     ret = (p2.getY() - p1.getY()) * (p2.getY() - p1.getY()) +
34           (p2.getX() - p1.getX()) * (p2.getX() - p1.getX()); //这个式中调用了八次函数,C++ 诞生初期,这么简单的计算要调用八次函数,和 C 相比效率低下,但是 C++ 设计初期要兼容包括 C 的高效等的一切特性,但是面向对象就有信息隐藏,所以诞生了友元;
35 */
36 
37     ret = (p2.y - p1.y) * (p2.y - p1.y) +
38           (p2.x - p1.x) * (p2.x - p1.x);
39 
40     ret = sqrt(ret);
41     
42     return ret;
43 }
44 
45 int main()
46 {
47     Point p1(1, 2);
48     Point p2(10, 20);
49     
50     printf("p1(%f, %f)
", p1.getX(), p1.getY());
51     printf("p2(%f, %f)
", p2.getX(), p2.getY());
52     printf("|(p1, p2)| = %f
", func(p1, p2));
53     
54     return 0;
55 }

    2,输出结果:

  p1(1.000000, 2.000000)

  p2(10.000000, 20.000000)

  |(p1, p2)| = 20.124612

   

6,友元的缺陷:

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

    2,友元直接破坏了面相对象的封装性;

       1,私有成员就不应该被外界访问;

    3,友元在实际产品中的高效是得不偿失的;

       1,破坏了封装性,导致很多的开发者将 C++ 作为 C 语言来使用;

    4,友元在现代软件工程中已经逐渐遗弃;

       1,成熟的产品中很少见到友元的身影;

       2,Java、C#、D 这些语言都诞生自 C++,但是都没有支持友元关系;

       3,在以后开发中,如果不是特别的关系,不要使用友元;

   

7,注意事项:

 

    1,友元关系不具备传递性;

    2,类的友元可以是其他类的成员函数;

    3,类的友元可以是某个完整的类;

       1,所有的成员函数都是友元,可以访问所有成员;

      

8,友元的深入分析编程实验:

    1,main.cpp 文件:

 1 #include <stdio.h>
 2 
 3 class ClassC
 4 {
 5     const char* n;  // 用于表示这个类的对象的名字;
 6 public:
 7     ClassC(const char* n)
 8     {
 9         this->n = n;  // 当前对象的初始值需要用构造函数的参数设置;
10     }
11     
12     friend class ClassB;  // B 是 C 的友元;
13 };
14 
15 class ClassB
16 {
17     const char* n;
18 public:
19     ClassB(const char* n)
20     {
21         this->n = n;
22     }
23     
24     void getClassCName(ClassC& c)  // 直接访问 C 的名字;
25     {
26         printf("c.n = %s
", c.n);
27     }
28     
29     friend class ClassA;  // A 是 B 的友元;
30 };
31 
32 class ClassA
33 {
34     const char* n;
35 public:
36     ClassA(const char* n)
37     {
38         this->n = n;
39     }
40     
41     void getClassBName(ClassB& b)  // 直接访问 B 的名字;
42     {
43         printf("b.n = %s
", b.n);
44     }
45 
46     /*
47     void getClassCName(ClassC& c)  // 友元不具备传递性;
48     {
49         printf("c.n = %s
", c.n);  // ‘const char* ClassC::n’ is  private within this context;
50     }
51     */
52 };
53 
54 int main()
55 {
56     ClassA A("A");
57     ClassB B("B");
58     ClassC C("C");
59     
60     A.getClassBName(B);
61     B.getClassCName(C);
62     
63     return 0;
64 }

    2,输出结果:

  b.n = B

  c.n = C

   

9,小结:

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

    2,友元直接破坏了面相对象的封装性;

    3,友元关系不具备传递性;

    4,类的友元可以是其它类的成员函数;

    5,类的友元可以是某个完整的类;

原文地址:https://www.cnblogs.com/dishengAndziyu/p/10907388.html