【C++基础入门】23.C++中的友元

编程入门 行业动态 更新时间:2024-10-25 18:36:09

【C++基础<a href=https://www.elefans.com/category/jswz/34/1770026.html style=入门】23.C++中的友元"/>

【C++基础入门】23.C++中的友元

文章目录

一、友元的概念

二、友元的用法

三、友元的语法

四、友元的尴尬

五、注意事项

六、小结


一、友元的概念

  • 什么是友元?
    • 友元是 C++ 中的一种关系
    • 友元关系发生在函数与类之间或者类与类之间
    • 友元关系是单项的,不能传递

二、友元的用法

  • 在类中以 friend 关键字声明友元
  • 类的友元可以是其它类或者具体函数
  • 友元不是类的一部分
  • 友元不受类中访问级别的限制
  • 友元可以直接访问具体类的所有成员

三、友元的语法

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

         先看一个不使用友元的代码:

#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.getY() - p1.getY()) * (p2.getY() - p1.getY()) +(p2.getX() - p1.getX()) * (p2.getX() - p1.getX());ret = sqrt(ret);return ret;
}int main()
{Point p1(1, 2);Point p2(10, 20);printf("p1(%f, %f)\n", p1.getX(), p1.getY());printf("p2(%f, %f)\n", p2.getX(), p2.getY());printf("|(p1, p2)| = %f\n", func(p1, p2));return 0;
}

        输出结果如下: 

         这个程序在x 和 y中计算两点之间的距离时需要频繁访问私有成员 x 和 y,所以不得不调用 getX() 和 getY() 来访问 x 和 y,x 和 y 函数中调用了 8 次 getX() 和 getY(),很麻烦。


        这个时候,就该我们的友元上场了: 

#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)\n", p1.getX(), p1.getY());printf("p2(%f, %f)\n", p2.getX(), p2.getY());printf("|(p1, p2)| = %f\n", func(p1, p2));return 0;
}

         输出结果如下:

 

四、友元的尴尬

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

五、注意事项

  • 友元关系不具备传递性
  • 类的友元可以是其它类的成员函数
  • 类的友元可以是某个完整的类
    • 所有的成员函数都是友元

        下面来深入分析一下友元: 

#include <stdio.h>class ClassC
{const char* n;
public:ClassC(const char* n){this->n = n;}friend class ClassB;
};class ClassB
{const char* n;
public:ClassB(const char* n){this->n = n;}void getClassCName(ClassC& c){printf("c.n = %s\n", c.n);}friend class ClassA;
};class ClassA
{const char* n;
public:ClassA(const char* n){this->n = n;}void getClassBName(ClassB& b){printf("b.n = %s\n", b.n);}/*void getClassCName(ClassC& c){printf("c.n = %s\n", c.n);}*/
};int main()
{ClassA A("A");ClassB B("B");ClassC C("C");A.getClassBName(B);B.getClassCName(C);return 0;
}

         B 是 C 的友元,A 是 B 的友元,输出结果如下:

         既然 A 可以访问 B,B 可以访问 C,那么 A 可以访问 C 么?把上面代码取消注释:

  void getClassCName(ClassC& c){printf("c.n = %s\n", c.n);}

        输出报错,这说明友元关系不具备传递性

 

六、小结

  • 友元是为了兼顾 C 语言的高效而诞生的
  • 友元直接破坏了面向对象的封装性
  • 友元关系不具备传递性
  • 类的友元可以是其它类的成员函数
  • 类的友元可以是某个完整的类
     

更多推荐

【C++基础入门】23.C++中的友元

本文发布于:2024-03-05 14:29:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1712547.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:入门   基础

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!