原文: https://www.programiz.com/cpp-programming/friend-function-class

在本文中,您将学习在 C++ 中创建友元函数和类,并在程序中有效地使用它们。

OOP 的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护数据。

但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。 因此,C++ 编程内置了一种机制,可以从非成员函数访问私有或受保护的数据。

这是通过使用好友函数或/和好友类完成的。


C++ 中的友元函数

如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。

编译器通过使用关键字friend知道给定的函数是友元函数。

为了访问数据,应该在类的主体内部(可以在类内部的任何地方,无论是私有的还是公共的部分),从关键字friend开始声明友元函数。


C++ 中的友元函数声明

  1. class class_name
  2. {
  3. ... .. ...
  4. friend return_type function_name(argument/s);
  5. ... .. ...
  6. }

现在,您可以将友元函数定义为访问该类数据的普通函数。 定义中未使用friend关键字。

  1. class className
  2. {
  3. ... .. ...
  4. friend return_type functionName(argument/s);
  5. ... .. ...
  6. }
  7. return_type functionName(argument/s)
  8. {
  9. ... .. ...
  10. // Private and protected data of className can be accessed from
  11. // this function because it is a friend function of className.
  12. ... .. ...
  13. }

示例 1:友元函数的工作原理

  1. /* C++ program to demonstrate the working of friend function.*/
  2. #include <iostream>
  3. using namespace std;
  4. class Distance
  5. {
  6. private:
  7. int meter;
  8. public:
  9. Distance(): meter(0) { }
  10. //friend function
  11. friend int addFive(Distance);
  12. };
  13. // friend function definition
  14. int addFive(Distance d)
  15. {
  16. //accessing private data from non-member function
  17. d.meter += 5;
  18. return d.meter;
  19. }
  20. int main()
  21. {
  22. Distance D;
  23. cout<<"Distance: "<< addFive(D);
  24. return 0;
  25. }

输出

  1. Distance: 5

在此,在Distance类内声明了友元函数addFive()。 因此,可以从此函数访问专用数据meter

尽管此示例为您提供了有关友元函数概念的想法,但并未显示任何有意义的用途。

当您需要对两个不同类的对象进行操作时,将有一种更有意义的用法。 那时,友元函数会非常有帮助。

您绝对可以在不使用友元函数的情况下对不同类的两个对象进行操作,但是该程序将很长,复杂且难以理解。


示例 2:使用友元函数相加两个不同类的成员

  1. #include <iostream>
  2. using namespace std;
  3. // forward declaration
  4. class B;
  5. class A {
  6. private:
  7. int numA;
  8. public:
  9. A(): numA(12) { }
  10. // friend function declaration
  11. friend int add(A, B);
  12. };
  13. class B {
  14. private:
  15. int numB;
  16. public:
  17. B(): numB(1) { }
  18. // friend function declaration
  19. friend int add(A , B);
  20. };
  21. // Function add() is the friend function of classes A and B
  22. // that accesses the member variables numA and numB
  23. int add(A objectA, B objectB)
  24. {
  25. return (objectA.numA + objectB.numB);
  26. }
  27. int main()
  28. {
  29. A objectA;
  30. B objectB;
  31. cout<<"Sum: "<< add(objectA, objectB);
  32. return 0;
  33. }

输出

  1. Sum: 13

在此程序中,类AB已将add()声明为友元函数。 因此,该函数可以访问两个类的私有数据。

在这里,add()函数将两个对象objectAobjectB的私有数据numAnumB相加,并将对象返回到main函数。

为了使该程序正常工作,应如上例所示对类类B进行前向声明。

这是因为在类A中使用代码friend int add(A , B);引用了类B


C++ 编程中的友元类

类似地,像友元函数一样,也可以使用关键字friend将一个类变成另一个类的友元。 例如:

  1. ... .. ...
  2. class B;
  3. class A
  4. {
  5. // class B is a friend class of class A
  6. friend class B;
  7. ... .. ...
  8. }
  9. class B
  10. {
  11. ... .. ...
  12. }

当一个类成为好友类时,该类的所有成员函数都将成为好友函数。

在此程序中,类B的所有成员函数将成为类A的友元函数。 因此,类B的任何成员函数都可以访问类A的私有数据和受保护的数据。但是,类A的成员函数不能访问类B的数据。

请记住,C++ 中的友元关系仅被授予,而不被接受。