友元函數:
友元函數可以直接通路類的私有成員,它是定義在類外的普通函數,不屬于任何類, 但需要在類内通過特殊的方式聲明,這裡特殊的方式指的就是在類内聲明時需加上 friend 關鍵字
class Date
{
//友元函數的聲明
friend ostream& operator <<(ostream& _cout, const Date& d);
public:
Date(int year,int month,int day)
:_year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
//友元函數作為普通函數,再類外的定義
ostream& operator <<(ostream& _cout, const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day << endl;
return _cout;
}
void test()
{
Date d(2018, 9, 7);
//想在這裡連續輸出就必須對上面函數設定傳回值
//設定成void 類型,不能連着用<< 運算符
cout << d << endl;
}
說明:
- 友元函數可以通路類的私有成員,但不是類的成員函數
- 友元函數不能用 const 修飾(因為它不是類的成員函數)
- 友元函數在類定義域内的任何地方都可聲明,不受類通路限定符的限制
- 一個函數可以是多個類的友元函數
- 友元函數的調用和普通函數的調用原理相同
友元類:
友元類的所有成員函數都可以是另一個類的成員函數,可以通路另一個類中的私有成員
class Time
{
//聲明日期類為時間類的友元類
//則在日期類中就直接通路Time類中的私有成員變量
friend class Date;
public:
//Time 類的構造函數需設計成預設的構造函數
//否則Date類的構造函數沒有能力構造出Time類對象
Time(int hour = 12,int minute = 0,int second = 0)
:_hour(hour)
,_minute(minute)
,_second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year,int month,int day)
:_year(year)
,_month(month)
,_day(day)
{}
void SetTime(int hour,int minute,int second)
{
//直接通路時間類私有的成員變量
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
友元的優缺點:
優點:提高了程式運作效率
缺點:破壞了類的封裝性和隐藏性
注意:
- 友元關系是單向的,不具有交換性
- 友元關系不能傳遞