面試的時候面試官問到了友元函數,自己其實之前對友元函數不是特別熟悉,只是略知一二;當然,回答的不是很讓面試官滿意,今天總體的再學習一下友元函數。
1.什麼是友元函數?
特點:
①在類中聲明的以friend關鍵字修飾的函數。
②形式表現:friend 返回類型 函數名 參數列表;
#include<iostream>
class func{
public:
func(int a)
: m_a(a)
{}
void generalFunc();
friend void friendfunc(); //該友元函數聲明爲public類型。
private:
friend void friendfunc(); //當然,友元函數也可以聲明爲private類型。
private:
int m_a;
}
//實現普通成員函數
void func::generalFunc() //普通成員函數在類外實現時,需要類名+::操作符
{
std::cout<<"This is generalFunc!"<<std::endl;
}
//實現友元函數 友元函數要在類外實現。
void friendFunc() //友元函數在類外實現的時候不需要帶類名。(因爲他壓根不是該類的成員函數)
{
std::cout<<"This is func's friend function!"<<std::endl;
}
2.什麼是友元類?
看了友元函數,可以聯想到友元類其實也是一樣的道理。
#include<iostream>
class A{
public:
A();
void func(int a)
{
std::cout << "A::func()" << std::endl;
}
private:
friend class Afrifunc; //Afrifunc是類A的友元類
int m_a;
}
class Afrifunc{ //實現友元類Afrifunc
//...
}
class B{
public:
B();
friend void A::func(int a); //類A的成員函數作爲了類B的友元函數。
private:
int m_b;
}
3.學會實現友元了,那我們使用的時候應該注意以下幾點:
①友元函數不能直接訪問類的成員,只能訪問對象成員。
②友元函數可以訪問對象的私有成員(這點普通函數不具備)
③調用友元時候要指出具體的對象。
④友元函數和友元類不繼承(因爲它壓根不屬於當前函數的成員)
⑤如上舉例所示,一個類的成員可以作爲另一個類的友元函數。
4.最重要的一點來了:
面試官這時候會問你,什麼時候使用友元函數?使用它的好與壞都有什麼?
1.先回到第一個問題,當我們需要提高效率或者爲了方便,我們會使用它。因爲普通函數無法訪問私有的成員,除非全部聲明爲共有的。但是有了友元這個機制,我們就可以訪問到對象的私有成員和數據了。
2.好處上面已經說了,是爲了方便和快速。但是它明顯的帶來了一定的壞處,那就是破壞了類的封裝性。(我校招的時候,某金融企業面試官問我繼承的缺點,實際上我想,繼承本身是爲了構建父子關係,但是它從一定程度上講,確實是破壞了子類的封裝性,因爲一個類被封裝了之後就表面其內容對其他類是不可見的,但是繼承卻可以通過不同的方式看到父類的一些信息。當然,這只是我個人體會的)。