一、友元函數定義:友元函數是指某些雖然不是類成員卻能夠訪問類的所有成員的函數。。類授予它的友元特別的訪問權。通常同一個開發者會出於技術和非技術的原因,控制類的友元和成員函數(否則當你想更新你的類時,還要徵得其它部分的擁有者的同意);類具有封裝和信息隱藏的特性。只有類的成員函數才能訪問類的私有成員,程序中的其他函數是無法訪問私有成員的。非成員函數可以訪問類中的公有成員,但是如果將數據成員都定義爲公有的,這又破壞了隱藏的特性。另外,應該看到在某些情況下,特別是在對某些成員函數多次調用時,由於參數傳遞,類型檢查和安全性檢查等都需要時間開銷,而影響程序的運行效率。
二、友元函數案例
1.全局友元函數
如果這個函數不是定義在class中,並且它可以用來操作其他class的私有屬性,稱之爲全局友元函數。案例如下:
#include <iostream>
using namespace std;
class A{
private:
int a;
public:
//申明友元函數
friend void show(A &a);
A(){
cout << "類A被構造" << endl;
a = 20;
}
~A(){
cout << "類A被析構" << endl;
}
};
//全局友元函數
void show(A &a){
//訪問classA的私有成員
cout << "a="<<a.a <<endl;
}
class B{
private:
int b;
public:
B(){
A a;
show(a);
cout << "類B的構造" << endl;
b = 12;
}
~B(){
cout << "類B被析構" << endl;
}
};
int main(){
B b;
return 0;
}
上述案例中void show(A &a) 爲全局友元函數,他可以訪問class A 的私有成員a,可以這樣理解,函數void show(...)是class A的朋友,故它可以訪問classA的資源。定義友元函數很簡單,只需要在class A中申明show函數,並在申明前添加frien關鍵字2.友元類
友元除了前面講過的函數以外,友元還可以是類,即一個類可以作另一個類的友元。當一個類作爲另一個類的友元時,這就意味着這個類的所有成員函數都是另一個類的友元函數。案例如下:
#include <iostream>
using namespace std;
class A{
private:
int a;
public:
friend class B;
A(){
cout << "類A被構造" << endl;
a = 20;
}
~A(){
cout << "類A被析構" << endl;
}
};
class B{
private:
int b;
public:
B(){
A a;
show(a);
cout << "類B的構造" << endl;
b = 12;
}
~B(){
cout << "類B被析構" << endl;
}
//友元類函數
void show(A &a){
//訪問classA的私有成員
cout << "a="<<a.a <<endl;
}
};
int main(){
B b;
return 0;
}
在class 中定義了friend class B;即class B 爲classA的友元類,classB 中的所有成員函數都是classA的友元函數,它們可以訪問classA 中的私有成員.注意這時,友元是單向的,這時class A 中的函數不能訪問class B中的內容。
3.互爲友元類
如何實現classA與B互爲友元,即A可以訪問B的私有,B也可以訪問A的私有呢?案例如下:
#include <iostream>
using namespace std;
//必須提前聲明class B不然編譯會報錯
class B;
class A{
private:
int a;
public:
friend class B;
A(){
cout << "類A被構造" << endl;
a = 20;
}
~A(){
cout << "類A被析構" << endl;
}
void show(B & b);
};
class B{
private:
int b;
public:
friend class A;
B(){
cout << "類B的構造" << endl;
b = 12;
}
~B(){
cout << "類B被析構" << endl;
}
void show(A &a){
cout << "a="<<a.a ;
cout << " b=" <<b<<endl;
}
};
//函數不能放在class A 中,不然會編譯報錯
void A::show(B &b){
cout << "a="<<a ;
cout << " b="<<b.b<< endl;
}
int main(){
A a;
B b;
a.show(b);
b.show(a);
return 0;
}
運行結果:
類A被構造
類B的構造
a=20 b=12
a=20 b=12
類B被析構
類A被析構
互爲友元類的做法就是,在classA中聲明friend
class
B;在classB 中聲明friend class A;注意:類A中使用到了類B的地方必須在類B的聲明後定義,在類A中只能聲明。例如左邊類A中的show函數,不能在類A中直接定義,只能放在類B的聲明之後定義。
文章出處:http://www.th7.cn/Program/cp/201411/320603.shtml