1. 程式人生 > 其它 >C++中的友元

C++中的友元

技術標籤:類和物件演算法c++

C++中的友元

友元的概念引入

C++的最重要的特點之一就是封裝性和繼承性。對於類的封裝性來說,就是類的私有成員和保護成員只能在設計類時它所定義的函式內使用,即私有成員和保護成員只能通過該類的成員函式來訪問。
當我們需要在類的外部訪問該類的私有成員和保護成員時,就可以利用友元(**friend**)來實現這一操作。

友元的分類

類的非成員函式友元

類的非成員函式友元:
   表示友元函式不是當前類的成員函式,而是獨立於當前類的外部函式,但是他可以訪問該類的所有成員(私有成員,保護成員,公有成員)。

注意:
(1)友元函式雖然可以訪問類的私有成員和保護成員,但是他不是該類的成員函式。所以,在外部定義友元函式時,需要在函式名前加上"類名::"。
(2)因為友元函式不是類的成員函式,沒有this指標來訪問物件的資料成員,不能直接訪問物件的資料成員,他必須通過作為入口引數傳遞進來的物件(引用)來訪問該物件的資料成員。例如:void fun(Object &obj)中的形參obj是Object類的物件的引用。

這裡給出程式碼示例和測試結果:

//類的非成員函式友元
class Object
{
	int value;
public:
	Object(int x = 0):value(x){ }//建構函式
	~Object(){}//解構函式
	void Print()
	{
		cout << "value:" << value << endl;
	}
	friend void fun(Object& obj);//函式友元
	//friend void fun是外部函式
};
class Test :public Object
{
private:
	int
num; }; void fun(Object &obj) { obj.value = 100;//設計該函式為友元函式 cout << "fun::value:" << obj.value << endl; } int main() { Object obj(10); obj.Print(); fun(obj); return 0; }

測試結果

類的成員函式友元

類的成員函式友元:
  表示友元函式在類中宣告,不僅可以訪問自己所在類物件中的私有成員和公有成員,還可以訪問friend宣告語句所在類物件中的所有成員。
注意:
(1)一個類的成員函式作為另一個類的友元函式,必須先定義這個類。

這裡給出程式碼示例和測試結果

//類的成員函式友元
class Base;
class Object
{
	int value;
public:
	Object(int x = 0) :value(x) {}
	~Object() {}
	void Print()
	{
		cout << "Object::value " << value << endl;
	}
	void func(Base& base);
};
class Base :public Object
{
private:
	int num;
public:
	Base(int x=0):num(x){}
	void Print()
	{
		cout << "Base::num " << num << endl;
	}
	friend void Object::func(Base& base);
};
void Object::func(Base& base)
{
	value = 200;
	base.num = 100;
	cout << "func::Object:value " << value << endl;
	cout << "func::Base:num " << base.num << endl;
}
int main()
{
	Object obj(10);
	Base base(0);

	obj.Print();
	base.Print();

	obj.func(base);

	return 0;
}

測試結果

類友元

一個類也可以作為另一個類的友元,稱為類友元。類友元的說明方法是在另一個類宣告中加入語句。這條語句可以放在公有部分也可以放在私有部分。
本示例中 friend class Object; 意思是:宣告類Object為類Base的友元類。

這裡給出程式碼示例和測試結果

//類友元
class Base;
class Object
{
	int value;
public:
	Object(int x = 0) :value(x) {}
	~Object() {}
	void Print()
	{
		cout << "Object::value " << value << endl;
	}
	void func(Base& base);
};
class Base :public Object
{
	friend class Object;//Object物件裡面的所有方法都能訪問Base裡面的私有屬性
private:
	int num;
public:
	Base(int x = 0) :num(x) {}
	void Print()
	{
		cout << "Base::num " << num << endl;
	}
};
void Object::func(Base& base)
{
	base.num = 100;
	value = 200;

	cout << "Object::func: num " << base.num << endl;
	cout << "Object::func:value " << value << endl;
}
int main()
{
	Object obj(10);
	Base base(0);

	obj.Print();
	base.Print();

	obj.func(base);

	return 0;
}

測試結果

友元的特點

不具有自反性(是單向的,fun是Object的友元,但是Object不是fun的友元)
不具有繼承性
不具有傳遞性

友元說明

友元是對類的封裝性的補充,利用這一點,一個類可以賦予某些函式訪問它的私有成員和保護成員的特權。
聲明瞭一個類的友元函式,就可以用這個函式直接訪問該類的私有成員和保護成員,從而提高程式執行的效率。
如果沒有友元,外部函式訪問類的私有資料,必須通過呼叫公有的成員函式,這會降低程式的執行效率。
友元提供了不同類的成員函式之間、類的成員函式與一般函式之間進行資料共享的機制。尤其是當一個函式需要訪問多個類時,友元函式非常有用,普通的成員函式只能訪問其所屬的類,但是多個類的友元函式能夠訪問相關的所有類的資料。