zoukankan      html  css  js  c++  java
  • 19 友元的尴尬能力

    1 友元的概念

    • 什么是友元?

      • 友元是 C++ 中的一种关系

      • 友元关系发生在函数与类之间或者类与类之间

      • 友元关系是单向的,不能传递

        • 左边的函数是右边类的友元,所以左边的函数可以访问右边类的成员

    • 友元的用法

      • 在类中以 friend 关键字声明友元
      • 类的友元可以是其他类或者具体函数
      • 友元不是类的一部分
      • 友元不受类中访问级别的限制
      • 友元可以直接访问具体类的所有成员 => 破坏了类的封装性
    • 友元的语法

      • 在类中用 friend 关键字对函数或类进行声明
    • 示例:友元的使用

      • Demo

        #include <stdio.h>
        #include <math.h>
        
        class Point
        {
            double x;
            double y;
        public:
            Point(double x, double y)
            {
                this->x = x;
                this->y = y;
            }
            
            double getX()
            {
                return x;
            }
            
            double getY()
            {
                return y;
            }
               
            friend double func(Point& p1, Point& p2);
        };
        
        double func(Point& p1, Point& p2)
        {
            double ret = 0;
            
            ret = (p2.y - p1.y) * (p2.y - p1.y) +
                  (p2.x - p1.x) * (p2.x - p1.x);
                  
            ret = sqrt(ret);
            
            return ret;
        }
        
        int main()
        {
            Point p1(1, 2);
            Point p2(10, 20);
            
            printf("p1(%f, %f)
        ", p1.getX(), p1.getY());
            printf("p2(%f, %f)
        ", p2.getX(), p2.getY());
            printf("|(p1, p2)| = %f
        ", func(p1, p2));
            
            return 0;
        }
        
      • 编译运行

        p1(1, 2)
        p2(10, 20)
        |(p1, p2)| = 20.124612
        

    2 友元的尴尬

    • 友元是为了兼顾 C 语言的高效而诞生的
    • 友元直接破坏了面对对象的封装性
    • 友元在实际产品中的高效是得不偿失的
    • 友元在现代软件工程中已经逐渐被遗弃

    3 注意事项

    • 友元关系不具备传递性

    • 类的友元可以是其他类的成员函数

    • 类的友元可以是某个完整的类

    • 示例:友元深入分析

      • Demo

        #include <stdio.h>
        
        class ClassC
        {
            const char* n;
        public:
            ClassC(const char* n)
            {
                this->n = n;
            }
            
            friend class ClassB;  //类B是类C的友元
        };
        
        class ClassB
        {
            const char* n;
        public:
            ClassB(const char* n)
            {
                this->n = n;
            }
            
            void getClassCName(ClassC& c)
            {
                printf("c.n = %s
        ", c.n);
            }
            
            friend class ClassA;  //类A是类B的友元
        };
        
        class ClassA
        {
            const char* n;
        public:
            ClassA(const char* n)
            {
                this->n = n;
            }
            
            void getClassBName(ClassB& b)
            {
                printf("b.n = %s
        ", b.n);
            }
            /*
            void getClassCName(ClassC& c)  //类A中不能直接访问类C的成员,不具备友元关系
            {
                printf("c.n = %s
        ", c.n);
            }
            */
        };
        
        int main()
        {
            ClassA A("A");
            ClassB B("B");
            ClassC C("C");
            
            A.getClassBName(B);
            B.getClassCName(C);
            
            return 0;
        }
        
      • 编译运行

        b.n = B
        c.n = C
        
  • 相关阅读:
    java连接zookeeper实现zookeeper的基本操作
    spring boot 中用@value给static变量赋值
    jquery 点击移动一次body
    Javascript实现导航锚点滚动效果实例
    vue.js 脚手架vue-cli构建了项目,想去除Eslint验证,如何设置?
    jquery 点击切换值
    js同时(onclick)调用多个方法
    修改输入框placeholder文字默认颜色css用法
    js获取星期几
    js计算器
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13722969.html
Copyright © 2011-2022 走看看