天天看點

C++中友元的使用方法(4-2)1 通路說明符2 友元3 友元與繼承

在C++中定義類時,可以通過三個通路說明符(access specifier)來指定其成員的通路權限。

1 通路說明符

這三個通路說明符分别是public、private和protected。其中,public表示該成員可以被所有的人通路;private則與public剛好相反,它表示該成員隻能被類内的成員函數通路;而protected表示該成員隻能被類内函數和該類的派生類對象通路。

2 友元

在“1通路說明符”中提到,類的private和protected成員不能被外部函數通路。如果外部函數确實需要通路這些成員,則可以将外部函數聲明為該類的友元。

2.1 聲明類的友元函數

通過關鍵字friend來聲明類的友元函數。例如

class X{
protected:
 int i;
friend void g(X* x, int i)
};
           

以上代碼将類外函數g()聲明成了類X的友元函數。

2.2 聲明及定義友元函數

在“2.1聲明類的友元函數”中隻是将函數g()聲明為類X的友元,并沒有對g()進行聲明和定義。接下來,在類X定義的外部,對g()進行聲明及定義。

void g(X *x, int i)
{
x->i = i;
}
           

從以上代碼中可以看到,在g()中可以通路X的private成員i了。

從以上分析可知,友元聲明隻能出現在類定義的内部,但在類内出現的具體位置不限。友元不是類的成員,也不受類通路說明符的限制。為了使友元對類使用者可見,通常把友元的聲明與類本身放置在同一個檔案中。

3 友元與繼承

3.1 繼承

通過繼承我們能夠定義這樣的類,它們對類型之間的關系模組化,共享公用的東西,僅僅特化本質上不同的東西。派生類能夠繼承基類定義的成員,還可以定義更多的成員。

3.2 派生類的友元

在“3.1繼承”中提到,派生類可以繼承基類的成員,但是派生類不能繼承基類的友元。即基類的友元在通路派生類成員時不具有特殊性,而派生類的友元也不能随意通路基類的成員。

class X_Base{
protected:
int i;
private:
int k;
};
class X_Derive:public X_Base{
friend void g(X_Derive* x, int i)
protected int j;
};
           

此時,在g()中可以通過X_Derive類的指針x通路X_Base的protected成員變量i和X_Derive的protected成員變量j,而不能通路X_Base的private成員變量k。

繼續閱讀