概念:在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)友元关系是单向的。