引入友元的目的
採用了類的機制後實現了資料的封裝與隱藏,只有類的成員函式才能訪問類的私有成員,外部函式只能訪問類的公有成員,不能訪問類的私有成員。 採用友元可以解決這一問題。 友元(friend, 即是“朋友”意思)可以在類外直接訪問類的私有成員,提高了程式的執行效率。
友元提供了在不同類的成員函式之間、類的成員函式與一般函式之間進行資料共享的機制。 通過友元,一個普通函式或另一個類中的成員函式可以訪問類中的私有成員。C++中的友元為封裝隱藏這堵不透明的牆開了一個小孔,外界可以通過這個小孔窺視內部的“祕密”。 友元的使用能提高程式的執行效率, 但破壞了類的封裝性和資料的隱蔽性,因此一定要謹慎使用。
友元的種類: 1)、友元函式:包括普通函式作為友元、其它類的成員函式作為友元 2)、友元類
友元函式
宣告:
格式1:
class 類名
{
…
friend 型別 函式名(形參表);
…
};
…
//函式的類外定義
型別 函式名(形參表)
{
…
}
複製程式碼
格式2:
class 類名
{
…
//函式的類內定義
friend 型別 函式名(形參表)
{
…
}
…
};
說明:格式1、格式2 只是友元函式定義的位置不同,兩者效果完全一樣。
複製程式碼
class A{
//友元函式
friend void modify_i(A *p, int a);
private:
int i;
public:
A(int i){
this->i = i;
}
void myprint(){
cout << i << endl;
}
};
//友元函式的實現,在友元函式中可以訪問私有的屬性
void modify_i(A *p, int a){
p->i = a;
}
void main(){
A* a = new A(10);
a->myprint();
modify_i(a,20);
a->myprint();
system("pause");
}
複製程式碼
說明: 1)友元函式的宣告可放在類的公有、私有或保護部分,結果是一樣的(下同,不再一一說明)。 2)友元函式雖是在類中說明的一個函式,它不是該類的成員函式,所以,函式定義時不需要在函式名前加類名::; 3)友元函式不是類的成員,所以沒有this指標,訪問該類的物件的成員時,必須使用物件名.成員名 格式。通常是用物件作為友元函式的引數; 4)友元函式的作用域從宣告點開始,結束點與類相同。因此,友元函式的宣告可以代替該函式的說明。
友元類
(1) 特點:該類的所有成員函式都是某一個類的友元函式。 (2)宣告格式:(類B是被訪問類,類A中的所有成員函式都是B的友元)
class B; //類B的提前引用宣告
class A //類A的定義
{… };
…
class B //類B的定義
{…
friend class A;
} ;
//類A的多個成員函式類外定義
型別 A::成員函式名(形參表){ … }
…
複製程式碼
//友元類
class A{
//友元類
friend class B;
private:
int i;
public:
A(int i){
this->i = i;
}
void myprint(){
cout << i << endl;
}
};
class B{
public:
//B這個友元類可以訪問A類的任何成員
void accessAny(){
a.i = 30;
}
private:
A a;
};
複製程式碼
說明:
1)友元類的所有成員函式都是友元函式,都具有訪問被訪問類所有成員的許可權; 2)這裡也涉及到兩個類:一個是被訪問的類,另一個是提供友元函式的訪問類,也存在被訪問類要提前宣告的問題; 3)請按如下次序進行宣告或定義,這樣不會出錯:被訪問類的提前宣告->定義友元類->定義被訪問的類(包含友元類的宣告)->友元類的所有成員函式類外定義。
呼叫:物件名.成員函式(實參表)