友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。
友元函数和类的成员函数的区别
成员函数有this指针,而友元函数没有this指针
友元函数是不能被继承的,也不能传递(B是A友元类,C是B友元类,C不是A友元类)
使用友元函数的优缺点
优点:能够提高效率,表达简单、清晰
缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数
1、将全局函数声明为友元函数
如果要将一个全局函数(Call)声明为本类(Time)的友元函数,则只需要在本类的函数声明部分声明该函数为friend 。此时,该函数可以访问本类的private 成员。
class Time{
public:
Time(int=1,int=1,int=1);
friend void call(Time &);//声明友元函数
private:
int hour;
int min;
int sec;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
void call(Time &t) {//全局函数,且是Time 类的友元函数
cout<<"Call:"<<t.hour<<"-"<<t.min<<"-"<<t.sec<<endl;//访问private 成员
}
int main()
{
Time t;
call(t);
system("PAUSE");
return EXIT_SUCCESS;
}
2、友元成员函数
如果需要将目标类(Time)中的成员函数(call)声明为本类(Date)的友元函数,则需要在本类的函数声明部分声明该函数为friend 。此时,该函数可以访问本类的private 成员。
class Date; //对Date 类的提前引用声明
class Time{
public:
Time(int=1,int=1,int=1);
void call(Date &);//声明成员函数
private:
int hour;
int min;
int sec;
};
class Date{
public:
Date(int=1,int=1,int=2008);
friend void Time::call(Date&); //声明Time 类的call 为本类的友元成员函数
private:
int year;
int mon;
int day;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
void Time::call(Date &d) {
cout<<"TIME:"<<hour<<"-"<<min<<"-"<<sec<<endl;
cout<<"DATE:"<<d.mon<<"-"<<d.day<<"-"<<d.year<<endl; //访问Date 类的private 成员
}
Date::Date(int m,int d,int y){
mon=m;
day=d;
year=y;
}
int main(){
Time t;
Date d;
t.call(d);
system("PAUSE");
return EXIT_SUCCESS;
}
3、将一个函数(全局或成员的)声明为多个类的友元函数
在这种情况下,该函数可以同时访问多个类的private 成员。class Date; //对Date 类的提前引用声明
class Time{
public:
Time(int=1,int=1,int=1);
friend void call(Time&,Date&);//声明函数call 为本类的友元成员函数
private:
int hour;
int min;
int sec;
};
class Date{
public:
Date(int=1,int=1,int=2008);
friend void call(Time&,Date&); //声明函数call 为本类的友元成员函数
private:
int year;
int mon;
int day;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
Date::Date(int m,int d,int y){
mon=m;
day=d;
year=y;
}
void call(Time &t,Date &d) {
cout<<"TIME:"<<t.hour<<"-"<<t.min<<"-"<<t.sec<<endl;
cout<<"DATE:"<<d.mon<<"-"<<d.day<<"-"<<d.year<<endl;
}
int main(){
Time t;
Date d;
call(t,d);
system("PAUSE");
return EXIT_SUCCESS;
}
4、友元类
可以将一个类(B)声明为当前类(A)的友元类。此时,友元类(B)中的所有成员函数都是当前类(A)的友元函数,可以访问当前类(A)的private 成员。
class Date; //对Date 类的提前引用声明
class Time{
public:
Time(int=1,int=1,int=1);
friend class Date;//将Date 类声明为当前类的友元类
private:
int hour;
int min;
int sec;
};
class Date{
public:
Date(int=1,int=1,int=2008);
void call_hour(Time&);
void call_min(Time&);
void call_sec(Time&);
private:
int year;
int mon;
int day;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
Date::Date(int m,int d,int y){
mon=m;
day=d;
year=y;
}
void Date::call_hour(Time &t){
cout<<"HOUR:"<<t.hour<<endl;
}
void Date::call_min(Time &t){
cout<<"MINUTE:"<<t.min<<endl;
}
void Date::call_sec(Time &t){
cout<<"SECOND:"<<t.sec<<endl;
}
int main(){
Time t;
Date d;
d.call_hour(t);
d.call_min(t);
d.call_sec(t);
system("PAUSE");
return EXIT_SUCCESS;
}