原文: https://www.programiz.com/cpp-programming/friend-function-class
OOP 的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护数据。
但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。 因此,C++ 编程内置了一种机制,可以从非成员函数访问私有或受保护的数据。
这是通过使用好友函数或/和好友类完成的。
如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。
编译器通过使用关键字friend
知道给定的函数是友元函数。
为了访问数据,应该在类的主体内部(可以在类内部的任何地方,无论是私有的还是公共的部分),从关键字friend
开始声明友元函数。
class class_name
{
... .. ...
friend return_type function_name(argument/s);
... .. ...
}
现在,您可以将友元函数定义为访问该类数据的普通函数。 定义中未使用friend
关键字。
class className
{
... .. ...
friend return_type functionName(argument/s);
... .. ...
}
return_type functionName(argument/s)
{
... .. ...
// Private and protected data of className can be accessed from
// this function because it is a friend function of className.
... .. ...
}
/* C++ program to demonstrate the working of friend function.*/
#include <iostream>
using namespace std;
class Distance
{
private:
int meter;
public:
Distance(): meter(0) { }
//friend function
friend int addFive(Distance);
};
// friend function definition
int addFive(Distance d)
{
//accessing private data from non-member function
d.meter += 5;
return d.meter;
}
int main()
{
Distance D;
cout<<"Distance: "<< addFive(D);
return 0;
}
输出
Distance: 5
在此,在Distance
类内声明了友元函数addFive()
。 因此,可以从此函数访问专用数据meter
。
尽管此示例为您提供了有关友元函数概念的想法,但并未显示任何有意义的用途。
当您需要对两个不同类的对象进行操作时,将有一种更有意义的用法。 那时,友元函数会非常有帮助。
您绝对可以在不使用友元函数的情况下对不同类的两个对象进行操作,但是该程序将很长,复杂且难以理解。
#include <iostream>
using namespace std;
// forward declaration
class B;
class A {
private:
int numA;
public:
A(): numA(12) { }
// friend function declaration
friend int add(A, B);
};
class B {
private:
int numB;
public:
B(): numB(1) { }
// friend function declaration
friend int add(A , B);
};
// Function add() is the friend function of classes A and B
// that accesses the member variables numA and numB
int add(A objectA, B objectB)
{
return (objectA.numA + objectB.numB);
}
int main()
{
A objectA;
B objectB;
cout<<"Sum: "<< add(objectA, objectB);
return 0;
}
输出
Sum: 13
在此程序中,类A
和B
已将add()
声明为友元函数。 因此,该函数可以访问两个类的私有数据。
在这里,add()
函数将两个对象objectA
和objectB
的私有数据numA
和numB
相加,并将对象返回到main
函数。
为了使该程序正常工作,应如上例所示对类类B
进行前向声明。
这是因为在类A
中使用代码friend int add(A , B);
引用了类B
。
类似地,像友元函数一样,也可以使用关键字friend
将一个类变成另一个类的友元。 例如:
... .. ...
class B;
class A
{
// class B is a friend class of class A
friend class B;
... .. ...
}
class B
{
... .. ...
}
当一个类成为好友类时,该类的所有成员函数都将成为好友函数。
在此程序中,类B
的所有成员函数将成为类A
的友元函数。 因此,类B
的任何成员函数都可以访问类A
的私有数据和受保护的数据。但是,类A
的成员函数不能访问类B
的数据。
请记住,C++ 中的友元关系仅被授予,而不被接受。