• 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,类的友元可以是某个完整的类;

    此文为作者学习唐佐林老师的学习笔记,仅为交流共享之用,由此带来的后果,与作者无关;转载请注明转载出处;难免有错,欢迎指正,联系方式qunchao24@sina.com。
  • 相关阅读:
    nginx 、tomcat 配置表单附件大小限制
    清理redis服务器数据
    tomcat 8.5.55 webapps 无法部署应用目录 org.apache.catalina.startup.HostConfig.deployDirectory
    redis + tomcat8.5 session共享
    linux tar 打包
    mysql ORDER BY RAND() 语句优化
    解决Linux下程序端口占用问题
    javamail邮件发送开发中SharedByteArrayInputStream类找不到的错误(java.lang.NoClassDefFoundError: com/sun/mail/util/SharedByteArrayInputStream)
    ansible判定文件或者文件夹是否存在
    ansible应用
  • 原文地址:https://www.cnblogs.com/sharecenter/p/14692347.html
Copyright © 2020-2023  润新知