举个现实中的例子,一般家庭都有客厅和卧室,我们将客厅比喻为公用部分(public),卧室比喻成私有部分(private),在类外只能访问公用成员,只有本类的函数才可以访问私有成员,我们可以把友元(friend)当做朋友,一般家庭会这么做,客厅(public)对所有来客开放,而卧室除了本家庭成员(private)可以进入之外,还允许朋友进入。
在C++中,友元可以访问与其有好友关系的类中的私有成员,友元包括友元函数和友元类。
如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为类的友元函数。友元函数可以访问类中的私有成员。
·
#include<iostream>
using namespace std;
class Time{
public:
Time(int,int,int);
friend void display(Time &);
private:
int hour;
int minute;
int sec;
};
Time::Time(int h,int m,int s){
hour=h;
minute=m;
sec=s;
};
void display(Time &t){
cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;
}
int main(){
Time t1(10,13,56);
display(t1);
return 0;
}
可以看出display在定义的时候没有声明为Time域,所以display()不属于Time类的函数,它是非成员函数,不属于任何类,如果在Time类中,没有声明它为友元函数,它不能引用Time中的私有成员的,因为display()函数不是Time类的成员函数,所以没有this指针。
#include<iostream>
using namespace std;
class Date;
class Time{
public:
Time(int,int,int);
void display(Date &);
private:
int hour;
int minute;
int sec;
};
class Date{
public:
Date(int,int,int);
friend void Time::display(Date &);
private:
int mouth;
int day;
int year;
};
Time::Time(int h,int m,int s){
hour=h;
minute=m;
sec=s;
}
void Time::display(Date &d){
cout<<d.month<<"/"<<d.day<<"/"<<d.year<<endl;
cout<<hour<<":"<<minute<<":"<<sec<<endl;
}
Date::Date(int m,int d,int y){
mouth=m;
day=d;
year=y;
}
int main(){
Time t1(10,13,56);
Date d1(12,25,2004);
t1.display(d1);
return 0;
}
运行结果:
12/25/2004
10:13:56
本来两个类是互不干扰的,但是display函数是Time类中的成员函数,它本来只能输出Time类中的数据,但是Date把他生命为朋友之后,他也可以访问Date类对象中的数据成员,但是参数需要时Date的对象。
不仅可以将一个函数声明为一个类的“朋友”,而且可以将一个类(B)声明为另一个类(A)的朋友,这时B类就是A类的友元类,友元类B中的所有函数都是A类的友元函数,可以访问A类中的所有成员
在A类定义体中用以下的语句声明B类为其友元类:
friend B;
声明友元类的一般形式为
friend 类名;
说明:
1.友元关系是单向的而不是双向的,如果声明B类是A类的友元类,不等于A类是B类的友元类,A类中的成员函数不能访问B类中的私有数据
2.友元关系不能传递。
原文:https://www.cnblogs.com/hj-SAMA/p/12287439.html