一、友元概述
举个现实中的例子,一般家庭都有客厅和卧室,我们将客厅比喻为公用部分(public),卧室比喻成私有部分(private),在类外只能访问公用成员,只有本类的函数才可以访问私有成员,我们可以把友元(friend)当做朋友,一般家庭会这么做,客厅(public)对所有来客开放,而卧室除了本家庭成员(private)可以进入之外,还允许朋友进入。
在C++中,友元可以访问与其有好友关系的类中的私有成员,友元包括友元函数和友元类。
二、友元函数
如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为类的友元函数。友元函数可以访问类中的私有成员。
·
1.将普通函数声明为友元函数
#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指针。
2.友元成员函数
#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