C++ 友元

鋸齒流沙發表於2017-12-26

引入友元的目的

採用了類的機制後實現了資料的封裝與隱藏,只有類的成員函式才能訪問類的私有成員,外部函式只能訪問類的公有成員,不能訪問類的私有成員。 採用友元可以解決這一問題。 友元(friend, 即是“朋友”意思)可以在類外直接訪問類的私有成員,提高了程式的執行效率。

友元提供了在不同類的成員函式之間、類的成員函式與一般函式之間進行資料共享的機制。 通過友元,一個普通函式或另一個類中的成員函式可以訪問類中的私有成員。C++中的友元為封裝隱藏這堵不透明的牆開了一個小孔,外界可以通過這個小孔窺視內部的“祕密”。 友元的使用能提高程式的執行效率, 但破壞了類的封裝性和資料的隱蔽性,因此一定要謹慎使用。

友元的種類: 1)、友元函式:包括普通函式作為友元、其它類的成員函式作為友元 2)、友元類

友元函式

宣告:

格式1:
class 類名
	{
	…
	friend 型別 函式名(形參表);
…
};
…
//函式的類外定義
型別 函式名(形參表)
{
	…
}
複製程式碼
格式2:
class 類名
	{
	…
	//函式的類內定義
	friend 型別 函式名(形參表)
{
		… 
	}
…
};

說明:格式1、格式2 只是友元函式定義的位置不同,兩者效果完全一樣。

複製程式碼
class A{
	//友元函式
	friend void modify_i(A *p, int a);
private:
	int i;
public:
	A(int i){
		this->i = i;
	}
	void myprint(){
		cout << i << endl;
	}
};


//友元函式的實現,在友元函式中可以訪問私有的屬性
void modify_i(A *p, int a){
	p->i = a;
}

void main(){
	A* a = new A(10);
	a->myprint();

	modify_i(a,20);
	a->myprint();

	system("pause");
}
複製程式碼

C++.png

說明: 1)友元函式的宣告可放在類的公有、私有或保護部分,結果是一樣的(下同,不再一一說明)。 2)友元函式雖是在類中說明的一個函式,它不是該類的成員函式,所以,函式定義時不需要在函式名前加類名::; 3)友元函式不是類的成員,所以沒有this指標,訪問該類的物件的成員時,必須使用物件名.成員名 格式。通常是用物件作為友元函式的引數; 4)友元函式的作用域從宣告點開始,結束點與類相同。因此,友元函式的宣告可以代替該函式的說明。

友元類

(1) 特點:該類的所有成員函式都是某一個類的友元函式。  (2)宣告格式:(類B是被訪問類,類A中的所有成員函式都是B的友元)

class B; 	   //類B的提前引用宣告
class A  	   //類A的定義   
	{… };
…
class B  	   //類B的定義 
	{…
	friend class A;
 } ;
	 //類A的多個成員函式類外定義
	 型別 A::成員函式名(形參表){ … }
 …

複製程式碼
//友元類
class A{
	//友元類
	friend class B;
private:
	int i;
public:
	A(int i){
		this->i = i;
	}
	void myprint(){
		cout << i << endl;
	}
};

class B{
public:
	//B這個友元類可以訪問A類的任何成員
	void accessAny(){
		a.i = 30;
	}
private:
	A a;
};
複製程式碼

說明:

1)友元類的所有成員函式都是友元函式,都具有訪問被訪問類所有成員的許可權; 2)這裡也涉及到兩個類:一個是被訪問的類,另一個是提供友元函式的訪問類,也存在被訪問類要提前宣告的問題; 3)請按如下次序進行宣告或定義,這樣不會出錯:被訪問類的提前宣告->定義友元類->定義被訪問的類(包含友元類的宣告)->友元類的所有成員函式類外定義。

呼叫:物件名.成員函式(實參表)

相關文章