友元在C++裏面是一個比較重要的東西,對於類裏面聲明的私有數據與函數,如果在某些應用需求下需要被其他函數調用,這時候就需要使用友元函數。就好像給了一個聲明,說某某函數是我這個類的一個好朋友,你們可以大膽地放他進入我的閨房,訪問我的數據。
在C++裏面,我們定義友元是使用friend 這個關鍵字。聲明友元函數可以有下面四種情況。
- class X {
- private:
- int i;
- public:
- friend void h();
- friend class Z;
- friend void g(X*, int);
- friend Y::f(X*);
- };
friend void h(); 聲明的友元函數是一個全局函數,這裏其實做了兩件事,一件事聲明一個函數 void h();,另一件事是聲明該函數屬於X類的一個友元函數。
friend class Z 聲明類Z是友元類,即類Z裏面所有方法都可以引用A中的私有數據與私有函數。
friend void g(X*, int) 這個是比較常用的方式,跟上面的全局函數是一樣的。
要強調的是friend Y::f(X*); 制定在類Y裏面的特定函數爲友元。這裏有一個問題要注意到,就是聲明的順序。在聲明友元函數之前必然是要求先聲明類Y以及類Y裏面的f()方法,不然系統是找不到對應的類。然後由於類Y裏面有類X作爲參數,也必然需要在聲明函數f()之前先有類X的聲明。這無疑是一個很大的矛盾。如何解決這個矛盾呢,是有技巧的。
- class X;
- class Y {
- void f(X*);
- };
- class X {
- private:
- int i;
- public:
- friend void h();
- friend class Z;
- frined void g(X*, int);
- friend Y::f(X*);
- };
如上面代碼所示,我們在聲明f(X*)之前有了類X的一個聲明,這裏僅僅是聲明,並沒有定義。在聲明友元之前也有類Y的一個聲明,這就圓了場。然而也要注意到,這裏有一個細節,f(X*)的參數是一個指針。由於在類Y前面類X只是一個聲明,但是對於類X的大小,在掃描到類Y時是未知的,所以只能傳入一個指針來解決這個衝突。