同類對象間無私處,異類對象間有友元
類的主要特點之一是數據隱藏,即類的私有成員無法在類的外部(作用域之外)訪問。但是,有時候需要在類的外部訪問類的私有成員,怎麼辦?
解決方法是使用友元函數,友元函數是一種特權函數,c++允許友元訪問私有成員。
可以把一個全局函數、某個類中的成員函數、甚至整個類聲明爲友元。
目錄
一、友元幾點說明
[友元類注意]
|
友元聲明以關鍵字friend開始,它只能出現在類定義中。因爲友元不是授權類的成員,所以它不受其所在類的聲明區域public
private和protected的影響。通常我們選擇把所有友元聲明組織在一起並放在類頭之後.
二、全局函數做友元
全局函數做友元固定格式:
在類的開頭,無需寫權限。關鍵字friend + 聲明要做友元的函數,在類外實現。
例子:
class Building
{
//讓全局函數 goodGay作爲本類Building中的好朋友,可以訪問私有成員
friend void goodGay(Building & building);
public:
Building()
{
m_SittingRoom = "客廳";
m_BedRoom = "臥室";
}
public:
//客廳
string m_SittingRoom;
private:
//臥室
string m_BedRoom;
};
//好基友 全局函數 可以訪問客廳 也可以訪問臥室
void goodGay(Building & building)
{
cout << "好基友正在訪問: " << building.m_SittingRoom << endl;
cout << "好基友正在訪問: " << building.m_BedRoom << endl;
}
int main(){
Building building;
goodGay(building);
system("pause");
return EXIT_SUCCESS;
}
三、類做友元
全局函數做友元固定格式:
在類的開頭,無需寫權限。關鍵字friend + 聲明要做友元的類。
例子:(讓GoodGay類作爲 Building類的好朋友,可以訪問Building類中私有成員)
class GoodGay
{
public:
GoodGay()
{
building = new Building;
}
void visit()
{
cout << "好基友類正在訪問: " << building->m_SittingRoom << endl;
cout << "好基友類正在訪問: " << building->m_BedRoom << endl;
}
Building * building;
};
class Building
{
//讓GoodGay類作爲 Building類的好朋友,可以訪問Building類中私有成員
friend class GoodGay;
public:
Building()
{
m_SittingRoom = "客廳";
m_BedRoom = "臥室";
}
string m_SittingRoom;
private:
string m_BedRoom;
};
int main(){
GoodGay gg;
gg.visit();
system("pause");
return EXIT_SUCCESS;
}
四、類中的成員做友元
全局函數做友元固定格式:
在類的開頭,無需寫權限。關鍵字friend + 聲明要做友元類中的成員。
class GoodGay
{
public:
GoodGay()
{
building = new Building;
}
//只有visit這個成員函數 ,可以訪問Building中的私有成員,其他函數不可以
void visit()
{
cout << "好基友的visit函數正在訪問: " << building->m_SittingRoom << endl;
cout << "好基友的visit函數正在訪問: " << building->m_BedRoom << endl;
}
Building * building;
};
class Building
{
//告訴編譯器 GoodGay類中的visit函數 是本類的好朋友,可以訪問本類中私有成員
friend void GoodGay::visit();
public:
Building()
{
m_SittingRoom = "客廳";
m_BedRoom = "臥室";
}
string m_SittingRoom; //客廳
private:
string m_BedRoom; //臥室
};
int main(){
GoodGay gg;
gg.visit();
system("pause");
return EXIT_SUCCESS;
}