C 友元類和友元函式詳解

2021-10-25 20:29:58 字數 2235 閱讀 6662

私有成員只能在類的成員函式內部訪問,如果想在別處訪問物件的私有成員,只能通過類提供的介面(成員函式)間接地進行。這固然能夠帶來資料隱藏的好處,利於將來程式的擴充,但也會增加程式書寫的麻煩。

c++ 是從結構化的c語言發展而來的,需要照顧結構化設計程式設計師的習慣,所以在對私有成員可訪問範圍的問題上不可限制太死。

c++ 設計者認為, 如果有的程式設計師真的非常怕麻煩,就是想在類的成員函式外部直接訪問物件的私有成員,那還是做一點妥協以滿足他們的願望為好,這也算是眼前利益和長遠利益的折中。因此,c++ 就有了友元(friend)的概念。打個比方,這相當於是說:朋友是值得信任的,所以可以對他們公開一些自己的隱私。

友元分為兩種:友元函式和友元類。

友元函式

在定義乙個類的時候,可以把一些函式(包括全域性函式和其他類的成員函式)宣告為「友元」,這樣那些函式就成為該類的友元函式,在友元函式內部就可以訪問該類物件的私有成員了。

將全域性函式宣告為友元的寫法如下:

friend 返回值型別 函式名(參數列);

將其他類的成員函式宣告為友元的寫法如下:

friend 返回值型別 其他類的類名::成員函式名(參數列);

但是,不能把其他類的私有成員函式宣告為友元。

關於友元,看下面的程式示例。

#include

using

namespace std;

class

ccar

;//提前宣告ccar類,以便後面的cdriver類使用

class

cdriver

;class

ccar

;void cdriver::

modifycar

(ccar* pcar)

intmostexpensivecar

(ccar cars,

int total)

//求最貴氣車的**

intmain()

這個程式只是為了展示友元的用法,所以 main 函式什麼也不做。

第 3 行宣告了 ccar 類,ccar 類的定義在後面。之所以要提前宣告,是因為 cdriver 類的定義中用到了 ccar 型別(第7行),而此時 ccar 類還沒有定義,編譯會報錯。

不要第 3 行,而把 ccar 類的定義寫在 cdriver 類的前面,是解決不了這個問題的,因為 ccar 類中也用到了 cdriver 型別(第14行),把 ccar 類的定義寫在前面會導致第 14 行的 cdriver 因沒有定義而報錯。c++ 為此提供的解決辦法是:可以簡單地將乙個類的名字提前宣告,寫法如下:

class 類名;

儘管可以提前宣告,但是在乙個類的定義出現之前,仍然不能有任何會導致該類物件被生成的語句。但使用該類的指標或引用是沒有問題的。

第 13 行將全域性函式 mostexpensivecar 宣告為 ccar 類的友元,因此在第 24 行可以訪問 cars[i] 的私有成員 price。同理,第 14 行將 cdriver 類的 modifycar 成員函式宣告為友元,因此在第 18 行可以訪問 pcar 指標所指向的物件的私有成員變數 price。

友元類

乙個類 a 可以將另乙個類 b 宣告為自己的友元,類 b 的所有成員函式就都可以訪問類 a 物件的私有成員。在類定義中宣告友元類的寫法如下:

friend class 類名;

來看如下例程:

class

ccar

;class

cdriver};

intmain()

第 5 行將 cdriver 宣告為 ccar 的友元類。這條語句本來就是在宣告 cdriver 是乙個類,所以 ccar 類定義前面就不用宣告 cdriver 類了。第 5 行使得 cdriver 類的所有成員函式都能訪問 ccar 物件的私有成員。如果沒有第 5 行,第 13 行對 mycar 私有成員 price 的訪問就會導致編譯錯誤。

一般來說,類 a 將類 b 宣告為友元類,則類 b 最好從邏輯上和類 a 有比較接近的關係。例如上面的例子,cdriver 代表司機,ccar 代表車,司機擁有車,所以 cdriver 類和 ccar 類從邏輯上來講關係比較密切,把 cdriver 類宣告為 ccar 類的友元比較合理。

友元關係在類之間不能傳遞,即類 a 是類 b 的友元,類 b 是類 c 的友元,並不能匯出類 a 是類 c 的友元。「咱倆是朋友,所以你的朋友就是我的朋友」這句話在 c++ 的友元關係上 不成立。

C 友元函式和友元類詳解

我們已知道類具備封裝和資訊隱 藏的特性。只有類的成員函式才能訪問類的私有成員,程式中的其他函式是無法訪問私有成員的。非成員函式能夠訪問類中的公有成員,但是假如將資料成員都定義 為公有的,這又破壞了隱藏的特性。另外,應該看到在某些情況下,特別是在對某些成員函式多次呼叫時,由於引數傳遞,型別檢查和安全性...

友元 友元函式 友元類和友元成員函式 C

有些情況下,允許特定的非成員函式訪問乙個類的私有成員,同時仍阻止一般的訪問,這是很方便做到的。例如被過載的操作符,如輸入或輸出操作符,經常需要訪問類的私有資料成員。友元 frend 機制允許乙個類將對其非公有成員的訪問權授予指定的函式或者類,友元的宣告以friend開始,它只能出現在類定義的內部,友...

友元 友元函式 友元類和友元成員函式 C

有些情況下,允許特定的非成員函式訪問乙個類的私有成員,同時仍阻止一般的訪問,這是很方便做到的。例如被過載的操作符,如輸入或輸出操作符,經常需要訪問類的私有資料成員。友元 frend 機制允許乙個類將對其非公有成員的訪問權授予指定的函式或者類,友元的宣告以friend開始,它只能出現在類定義的內部,友...