服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++超详细讲解友元的使用

C++超详细讲解友元的使用

2022-11-14 13:55清风自在 流水潺潺 C/C++

采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数

一、友元的概念

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

C++超详细讲解友元的使用

 

二、友元的用法

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

 

三、友元的语法

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

C++超详细讲解友元的使用

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

#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;
}

输出结果如下:

C++超详细讲解友元的使用

这个程序在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++超详细讲解友元的使用

 

四、友元的尴尬

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

 

五、注意事项

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

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 的友元,输出结果如下:

C++超详细讲解友元的使用

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

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

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

C++超详细讲解友元的使用

 

六、小结

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

到此这篇关于C++超详细讲解友元的使用的文章就介绍到这了,更多相关C++友元内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_43129713/article/details/124266824

延伸 · 阅读

精彩推荐
  • C/C++深入理解C++内链接与外链接的意义

    深入理解C++内链接与外链接的意义

    链接描述了名称在整个程序或一个翻译单元中如何引用或不引用同一实体,下面这篇文章主要给大家介绍了关于C++内链接与外链接意义的理解,需要的朋友可...

    Jerish_C11162022-02-24
  • C/C++C++类中的常量介绍

    C++类中的常量介绍

    const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同...

    C++教程网4892021-01-05
  • C/C++C语言实现经典24点算法

    C语言实现经典24点算法

    这篇文章主要为大家详细介绍了C语言实现经典24点算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    mingwar12052021-08-04
  • C/C++Visual Studio Code (VSCode) 配置搭建 C/C++ 开发编译环境的流程

    Visual Studio Code (VSCode) 配置搭建 C/C++ 开发编译环境的流程

    记得N年前刚开始接触编程时,使用的是Visual C++6.0,下面这个可爱的图标很多人一定很熟悉。不过今天想尝鲜新的工具 Visual Studio Code 来搭建C/C++开发环境,...

    Hi,出发了4422022-01-17
  • C/C++利用C++如何覆盖或删除指定位置的文件内容

    利用C++如何覆盖或删除指定位置的文件内容

    这篇文章主要给大家介绍了关于利用C++如何覆盖或删除指定位置的文件内容,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学...

    Dablelv8862021-05-27
  • C/C++c语言 汉诺塔算法代码

    c语言 汉诺塔算法代码

    c语言 汉诺塔算法代码,需要的朋友可以参考一下...

    C语言教程网1692020-11-22
  • C/C++C语言结构体超详细讲解

    C语言结构体超详细讲解

    C语言结构体(Struct)从本质上讲是一种自定义的数据类型,只不过这种数据类型比较复杂,是由 int、char、float 等基本类型组成的。你可以认为结构体是一...

    初学C语言者9492022-11-08
  • C/C++总结c++性能优化策略

    总结c++性能优化策略

    在本篇文章中小编给大家总结了关于C++的性能优化策略的相关知识点,对此有兴趣的朋友可以参考学习下。...

    D_Guco12252021-06-22