OOP的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护的数据。
但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。因此,C ++编程内置了一种机制,可以从非成员函数访问私有或受保护的数据。
这是使用友元函数和友元类完成的。
C ++中的友元函数
如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。
通过使用关键字friend,编译器知道给定的函数是友元函数。
要访问数据,应该在类的内部以关键字friend开始声明友元函数(可以是类内部的任何地方,可以是private部分,也可以是public部分)。
C ++中的友元函数声明
class class_name
{
... .. ...
friend return_type function_name(argument/s);
... .. ...
}
现在,您可以将友元函数定义为访问该类数据的普通函数。friend定义中未使用任何关键字。
class className
{
... .. ...
friend return_type functionName(argument/s);
... .. ...
}
return_type functionName(argument/s)
{
... .. ...
// 可以从这个位置访问className的私有和受保护数据
//因为此函数是className的友元函数。
... .. ...
}
示例:友元函数的工作
/* C ++程序演示友元函数的工作。*/
#include <iostream>
using namespace std;
class Distance
{
private:
int meter;
public:
Distance(): meter(0) { }
//友元函数
friend int addFive(Distance);
};
// 友元函数的定义
int addFive(Distance d)
{
//从非成员函数访问私有数据
d.meter += 5;
return d.meter;
}
int main()
{
Distance D;
cout<<"距离: "<< addFive(D);
return 0;
}
输出结果
距离: 5
这里,友元函数addFive()在Distance类中声明。因此,可以从这个函数访问私有数据。
尽管此示例为您提供了有关友元函数概念的想法,但并未显示任何有意义的用途。
当您需要对两个不同类的对象进行操作时,将有一种更有意义的用法。那时,友元函数会非常有帮助。
你完全可以在不使用friend函数的情况下操作两个不同类的对象,但是这个程序会很长,很复杂,很难理解。
示例:使用友元函数添加两个不同类的成员
#include <iostream>
using namespace std;
// 前置声明
class B;
class A {
private:
int numA;
public:
A(): numA(12) { }
//友元函数声明
friend int add(A, B);
};
class B {
private:
int numB;
public:
B(): numB(1) { }
// 友元函数声明
friend int add(A , B);
};
//函数add()是类A和B的友元函数
//访问成员变量numA和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()声明为friend函数。因此,这个函数可以访问这两个类的私有数据。
在这里,add()函数将两个对象objectS和object的私有数据numA和numB相加,并将其返回给main函数。
为了使这个程序正常工作,应该像上面的实例中所示的那样,对一个类B进行前置声明。
这是因为使用以下代码在class A中引用了class B的友元函数:friend int add(A,B);
C ++编程中的友元类(friend class)
类似地,像一个友元函数一样,一个类也可以使用关键字friend成为另一个类的友元类。例如:
... .. ...
class B;
class A
{
// class B 是 class A的友元类
friend class B;
... .. ...
}
class B
{
... .. ...
}
当一个类成为另一个类的friend类(友元类)时,这就意味着这个类的所有成员函数都是另一个类的友元函数。
在这个程序中,B类的所有成员函数都是A类的朋友函数,因此B类的任何成员函数都可以访问A类的私有和受保护的数据,但是A类的成员函数不能访问B类的数据。
C ++编程中如何互为友元类
如何实现classA与B互为友元,即A可以访问B的私有,B也可以访问A的私有呢?案例如下:
#include <iostream>
using namespace std;
//必须提前声明class B不然编译会报错
class B;
class A{
private:
int a;
public:
friend class B;
A(){
cout << "类A被构造" << endl;
a = 20;
}
~A(){
cout << "类A被析构" << endl;
}
void show(B & b);
};
class B{
private:
int b;
public:
friend class A;
B(){
cout << "类B的构造" << endl;
b = 12;
}
~B(){
cout << "类B被析构" << endl;
}
void show(A &a){
cout << "a="<<a.a ;
cout << " b=" <<b<<endl;
}
};
//函数不能放在class A 中,不然会编译报错
void A::show(B &b){
cout << "a="<<a ;
cout << " b="<<b.b<< endl;
}
int main(){
A a;
B b;
a.show(b);
b.show(a);
return 0;
}
运行结果:
类A被构造
类B的构造
a=20 b=12
a=20 b=12
类B被析构
类A被析构
互为友元类的做法就是,在class A中声明friend class B;在classB 中声明friend class A;
注意:类A中使用到了类B的地方必须在类B的声明后定义,在类A中只能声明。例如左边类A中的show函数,不能在类A中直接定义,只能放在类B的声明之后定义。