概念:在C++中,类具有封装性和隐蔽性,只有类的函数成员才能访问类的私有成员,程序中的其他函数是无法访问类的私有成员,友元为类的封装隐藏开了一个小孔,外界可以访问类内部的一些属性。如果某个对象说明为某个类的友元函数,那么这个外界对象就可以访问这个类对象中的私有成员。
PS:友元不是类的成员,但它可以访问类的任何成员。
友元分为友元函数和友元类。
一、友元函数
计算火车旅途时间的友元函数
//定义一个Clock的类,TrianTime是它的友元函数
#include<iostream>
using namespace std;
class Clock
{
public:
Clock(int h = 0,int m = 0,int s = 0)//构造函数
{
this -> H = h;
this -> M = m;
this -> S = s;
}
void SetTime(int h,int m,int s)//建立时间
{
this -> H = h;
this -> M = m;
this -> S = s;
}
void ShowTime()//打印时间
{
cout << H << ":" << M << ":" << S << endl;
}
friend Clock TrianTime(Clock & StartTime,Clock & EndTime); //友元函数声明
private:
int H;
int M;
int S;
};
Clock TrianTime(Clock & StartTime,Clock & EndTime) //友元函数定义时不需要加 friend
{
int tH = 0;
int tM = 0;
int tS = 0;
int carry = 0; //借位
Clock tTime;
( tS = EndTime.S - StartTime.S) > 0 ? carry = 0 : carry = 1 , tS += 60;
( tM = EndTime.M - StartTime.M - carry ) > 0 ? carry = 0 : carry = 1 , tM += 60;
( tH = EndTime.H - StartTime.H -carry ) > 0 ? carry = 0 : tH += 24;
tTime.SetTime(tH,tM,tS);
return tTime;
}
int main()
{
Clock C1(8,10,10);//定义一个Clock对象
Clock C2(6,1,2);
Clock C3;//定义Clock类的对象,存储结果
C3 = TrianTime(C1,C2);
C3.ShowTime();
return 0;
}
运行结果:
PS:
(1)在类外定义友元函数,不需要加上作用域(Clock::)
(2)调用友元函数如果通过对象调用,C1.TrainTime() 是错的
二、友元类
计算火车旅途时间的友元类
//Clock.h
#include<iostream>
using namespace std;
class Clock
{
public:
Clock(int h = 0,int m = 0,int s = 0)
{
this -> H = h;
this -> M = m;
this -> S = s;
}
void SetTime(int h = 0,int m = 0,int s = 0)
{
this -> H = h;
this -> M = m;
this -> S = s;
}
void ShowTime()
{
cout << H << ":" << M << ":" << S << endl;
}
friend class TrainTrip;
private:
int H;
int M;
int S;
};
#include<iostream>
#include"Clock.h"
using namespace std;
//TrainTrip.h
class TrainTrip
{
public:
TrainTrip(char * no,Clock s,Clock e)
{
this -> TrainNo = no;
this -> StartTime = s;
this -> EndTime = e;
}
Clock TrainTime()
{
int tH = 0;
int tM = 0;
int tS = 0;
int carry = 0; //借位
Clock tTime;
( tS = EndTime.S - StartTime.S) > 0 ? carry = 0 : carry = 1 , tS += 60;
( tM = EndTime.M - StartTime.M - carry ) > 0 ? carry = 0 : carry = 1 , tM += 60;
( tH = EndTime.H - StartTime.H -carry ) > 0 ? carry = 0 : tH += 24;
tTime.SetTime(tH,tM,tS);
return tTime;
}
private:
char * TrainNo;//车次
Clock StartTime;//出发时间
Clock EndTime;//到达时间
};
//main.cpp
#include<iostream>
#include"TrainTrip.h"
using namespace std;
int main()
{
Clock C1(8,10,10);
Clock C2(6,1,2);
Clock C3;
TrainTrip T1( "K16",C1,C2);
C3 = T1.TrainTime();
C3.ShowTime();
return 0;
}
运行结果同上
性质:
(1)友元关系不能传递。
(2)友元关系是单向的。