友元是一種定義在類外部的普通函數或類,但它需要在類體內進行說明,爲了與該類的成員函數加以區別,在說明時前面加以關鍵字friend。
友元不是成員函數,但是它可以訪問類中的私有成員。
友元的作用在於提高程序的運行效率,但是,它破壞了類的封裝性和隱藏性,使得非成員函數可以訪問類的私有成員。
有兩種形式的友元:
(1)友元函數:普通函數對一個訪問某個類中的私有或保護成員。
(2)友元類:類A中的成員函數訪問類B中的私有或保護成員。
友元函數:
在類聲明的任何區域中聲明,而定義則在類的外部。
friend <類型><友元函數名>(<參數表>);
示例:
class A
{
public:
A(int _a):a(_a){};
friend int getA_a(A &_classA);//友元函數
private:
int a;
};
int getA_a(A &_classA)
{
return _classA.a;//通過對象名訪問私有變量
}
int _tmain(int argc, _TCHAR* argv[])
{
A _classA(3);
std::cout<<getA_a(_classA);//友元函數只是普通函數,可以在任意地方調用
return 0;
}
需要注意的是:
(1)友元函數不是類成員函數,沒有this指針。
(2)友元函數是類外的函數,所以它的聲明可以放在類的私有段或公有段且沒有區別。
(3)友元函數只是一個普通函數,並不是該類的類成員函數,它可以在任何地方調用,友元函數中通過對象名來訪問該類的私有或保護成員。
友元類:
可以理解爲:類B的所有成員函數都爲類A的友元函數,則類B爲類A的友元類。
friend class <友元類名>;
示例:
class girl;
class boy
{
public:
void disp(girl &);
};
void boy::disp(girl &x) //函數disp()爲類boy的成員函數,也是類girl的友元函數
{
cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl;//藉助友元,在boy的成員函數disp中,藉助girl的對象,直接訪問girl的私有變量
}
class girl
{
private:
char *name;
int age;
friend boy; //聲明類boy是類girl的友元
};
需要注意的是,友元類沒有繼承性和傳遞性
(1)沒有繼承性:假如類B是類A的友元,類C繼承於類A,那麼友元類B是沒辦法直接訪問類C的私有或保護成員。
(2)沒有傳遞性:假如類B是類A的友元,類C是類B的友元,那麼友元類C是沒辦法直接訪問類A的私有或保護成員,也就是不存在“友元的友元”這種關係。