一、引入友元機制的原因
1. 在不放棄私人資料安全性的情況下,使得類外部的函數或類能夠訪問類中的私人成員,在c++中就用友元作為實現這個要求的輔助手
段。
2. 聲明了一個類的友元函數,就可以用這個函數直接存取該類的私人資料,從而提高了程式啟動並執行效率。(如果沒有友元機制,外部函
數訪問類的私人資料,必須通過調用公有的成員函數才能訪問私人資料,這在需要頻繁調用私人資料的情況下,會帶來較大的開銷,
從而降低程式的運行效率)
3. 方便編程,在某些情況下,如運算子被重載時,需要用到友元函數。
4. 友元提供了不同類的成員函數之間、類的成員函數與一般函數之間進行資料共用的機制。
5. 友元既可以是不屬於任何類的一般函數,也可以是另一個類的成員函數,還可以是整個的一個類(這個類中的所有成員函數都可以成
為友元函數)。
二、友元函數
聲明格式:
friend 傳回型別 函數名(參數表);
說明:
1. 聲明友元函數時,可放在公用部分,也可放在私人部分;可定義在類內部,也可定義在類外部;
2. 友元函數不是當前類的成員函數,而是獨立於當前類的外部函數,但它可以訪問該類的所有對象的成員,包括私人成員和公有成
員;
3. 在類外部定義友元函數時,不必像成員函數那樣,在函數名前加上“類名::”;(因為它不是成員函數)
4. 友元函數一般帶有一個該類的入口參數,它必須通過作為入口參數傳遞進來的對象名或對象指標來引用該對象的成員;(因為友
元函數不是類的成員,所以它不能直接引用對象成員的名字,也不能通過this指標引用對象的成員)
例子:
#include <iostream><br />#include <string.h><br />#include <cstdlib></p><p>using namespace std;</p><p>class KGirl<br />{<br />char *name;<br />int age;<br />public:<br />KGirl(char *n, int d)<br />{<br />name = new char[strlen(n) + 1];<br />strcpy(name, n);<br />age = d;<br />}<br />friend void Disp(KGirl &); //聲明友元函數<br />~KGirl()<br />{<br />delete name;<br />}<br />};</p><p>void Disp(KGirl &x) //定義友元函數<br />{<br />cout<<"girl/'s name is: "<<x.name<<", age: "<<x.age<<"/n";<br />}</p><p>int main()<br />{<br />KGirl e("Chen Xingwei",18);<br />Disp(e); //調用友元函數<br />return 0;<br />}
三、友元成員
定義格式:
friend 傳回型別 函數所在類名::函數名(參數表);
說明:
1. 友元成員是指一個類的成員函數作為另一個類的友元函數;
2. 一個類的成員函數作為另一個類的友元函數時,必須先定義這個類;
3. 這種友元成員函數不僅可以訪問自己所在類對象中的私人成員和公有成員,還可以訪問friend聲明語句所在類對象中的私人成員
和公有成員,這樣能使兩個類相互合作、協調工作,完成某一任務。
例子:
#include <iostream><br />#include <string.h><br />#include <cstdlib></p><p>using namespace std;<br />class KGirl; //向前引用<br />class KBoy<br />{<br />char *name;<br />int age;<br />public:<br />KBoy(char *n, int d)<br />{<br />name = new char[strlen(n) + 1];<br />strcpy(name, n);<br />age = d;<br />}<br />void Disp(KGirl &); //聲明Disp()為類KBoy的成員函數<br />~KBoy()<br />{<br />delete name;<br />}<br />};</p><p>class KGirl<br />{<br />char *name;<br />int age;<br />public:<br />KGirl(char *n, int d)<br />{<br />name = new char[strlen(n) + 1];<br />strcpy(name, n);<br />age = d;<br />}<br />friend void KBoy::Disp(KGirl &); //聲明類KBoy的成員函數Disp()為類KGirl的友元函數<br />~KGirl()<br />{<br />delete name;<br />}<br />};</p><p>void KBoy::Disp(KGirl &x) //定義友元函數Disp()<br />{<br />cout<<"boy/'s name is: "<<name<<", age: "<<age<<"/n"; //訪問本類對象成員<br />cout<<"girl/'s name is: "<<x.name<<", age: "<<x.age<<"/n"; //訪問友類對象成員<br />}</p><p>int main()<br />{<br />KBoy b("chen hao", 25);<br />KGirl e("zhang wei", 18);<br />b.Disp(e);<br />return 0;<br />}</p><p>
程式結果:
boy's name is: chen hao, age: 25
girl's name is: zhang wei, age: 18
四、友元類
定義格式:
friend 類名;
說明:
1. 友元類的聲明可放在類的公有部分,也可以放在私人部分;
2. 當一個類被說明為另一個類的友元時,它的所有的成員函數都可成為另一個類的友元函數,也就是說,作為友元的類中的所有
成員函數都可以訪問另一個類中的私人成員;
3. 友元關係是單向的,不具有交換性,也不具有傳遞性。(如:類x是類y的友元,但類y不一定是類x的友元;類x是類y的友元
類y是類z的友元,則類x不一定是類z的友元)
例子:
#include <iostream><br />#include <string.h><br />#include <cstdlib></p><p>using namespace std;<br />class KGirl; //向前引用<br />class KBoy<br />{<br />char *name;<br />int age;<br />public:<br />KBoy(char *n, int d)<br />{<br />name = new char[strlen(n) + 1];<br />strcpy(name, n);<br />age = d;<br />}<br />void Disp(KGirl &); //聲明Disp()為類KBoy的成員函數<br />~KBoy()<br />{<br />delete name;<br />}<br />};</p><p>class KGirl<br />{<br />char *name;<br />int age;<br />friend KBoy; //聲明類KBoy是類KGirl的友元<br />public:<br />KGirl(char *n, int d)<br />{<br />name = new char[strlen(n) + 1];<br />strcpy(name, n);<br />age = d;<br />}<br />~KGirl()<br />{<br />delete name;<br />}<br />};</p><p>void KBoy::Disp(KGirl &x) //定義友元函數Disp(),它是類KBoy的成員函數,<br /> //也是類KGirl的友元函數<br />{<br />cout<<"boy's name is: "<<name<<", age: "<<age<<"/n";<br />cout<<"girl's name is: "<<x.name<<", age: "<<x.age<<"/n";<br />}</p><p>int main()<br />{<br />KBoy b("chen hao", 25);<br />KGirl e("zhang wei", 18);<br />b.Disp(e);<br />return 0;<br />}</p><p>
程式結果:
boy's name is: chen hao, age: 25
girl's name is: zhang wei, age: 18