1.概述
友元提供了一種 普通函數或者類成員函數 通路另一個類中的私有或保護成員 的機制。也就是說有兩種形式的友元:
(1)友元函數:普通函數對一個通路某個類中的私有或保護成員。
(2)友元類:類A中的成員函數通路類B中的私有或保護成員。
2.特性
優點:提高了程式的運作效率。
缺點:破壞了類的封裝性和資料的透明性。
3.實作
3.1.友元函數
3.1.1.聲明和定義
在類聲明的任何區域中聲明,而定義則在類的外部。
friend <類型><友元函數名>(<參數表>);
注意,友元函數隻是一個普通函數,并不是該類的類成員函數,它可以在任何地方調用,友元函數中通過對象名來通路該類的私有或保護成員。
3.1.2.示例
// TestFriend.cpp
#include "stdafx.h"
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;
}
3.2.友元類
3.2.1.聲明和定義
友元類的聲明在該類的聲明中,而實作在該類外。
friend class <友元類名>;
友元類的執行個體則在main函數中定義。
3.2.2.示例
// TestFriend.cpp
#include "stdafx.h"
class B
{
public:
B(int _b):b(_b){};
friend class C;//聲明友元類C
private:
int b;
};
class C//實作友元類C
{
public:
int getB_b(B _classB){
return _classB.b;//通路友元類B的私有成員
};
};
int _tmain(int argc, _TCHAR* argv[])
{
B _classB(3);
C _classC;//定義友元類執行個體
std::cout<<_classC.getB_b(_classB);
return 0;
}
4.注意
4.1.友元關系沒有繼承性
假如類B是類A的友元,類C繼承于類A,那麼友元類B是沒辦法直接通路類C的私有或保護成員。
4.2.友元關系沒有傳遞性
加入類B是類A的友元,類C是類B的友元,那麼友元類C是沒辦法直接通路類A的私有或保護成員,也就是不存在“友元的友元”這種關系。