對c 友元函式和友元類的理解

2021-07-14 01:29:12 字數 1805 閱讀 4473

1,友元函式的定義和作用

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

為了解決上述問題,提出一種使用友元的方案。友元是一種定義在類外部的普通函式,但它需要在類體內進行說明,為了與該類的成員函式加以區別,在說明時前面加以關鍵字friend。友元不是成員函式,但是它可以訪問類中的私有成員。友元的作用在於提高程式的執行效率(即減少了型別檢查和安全性檢查等都需要的時間開銷),但是,它破壞了類的封裝性和隱藏性,使得非成員函式可以訪問類的私有成員。

2,上述的訪問不是直接訪問,對於普通私有成員變數是通過物件訪問,對於私有靜態變數是通過類訪問。

為什麼不能直接訪問呢?

先了解一下為什麼成員函式可以直接訪問成員變數?

成員函式能夠訪問類的成員變數是因為傳遞了指向當前物件的this指標,它如果訪問資料成員對其操作是this指向的物件的資料成員,是有實際意義的 。

友元函式不是成員函式,沒有傳遞隱藏的this指標,只能間接訪問。

這點其實和靜態成員函式一樣,靜態成員函式也是沒有this指標的,所以它只能訪問靜態成員變數或者通過物件訪問非靜態成員變數。

例子:class rect

//rect(const rect& r)

// ~rect() // 析構函式,計數器減1

static int getcount() // 返回計數器的值

friend int get();

private:

int width;

int height;

static int count; // 一靜態成員做為計數器

};

int rect::count = 0; // 初始化計數器

int get()

int main()

friend

class

b;   

};   

class

b   

};   

class

c:public

b  ;   

void

main()   

1.2.base的友元可以通過base的派生類drived訪問base的private,protect成員變數,但不能訪問drived的private,protect成員變數。(這一點似乎與《c++ primer》裡說的有點衝突)

個人理解:drived的物件本身就包含base,base的友元frnd自然就可以訪問base的部分。

[cpp]view plain

copy

#include 

using

namespace

std;   

class

base   

friend

class

frnd;   

};   

class

drived:

public

base   

};  

class

frnd   

};   

intmain()   

3 友元類的傳遞問題

a的友元是b,b的友元是c,那a的友元是c? 不是,友元類不具有傳遞性。

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

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

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

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

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

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