天天看點

友元函數C++筆記四:友元

本文筆者在青島逛街的時候突然想到的...今天就有想寫幾篇關于友元函數的筆記,是以回家到以後就奮筆疾書的寫出來釋出了

           友元 friend     

           有時候你須要拜訪一個類的所有成員,而這類拜訪方法在邏輯上又不是被拜訪類的接口。你也不希望破壞類的權限機制。比如你希望能給你的寵物對象取名字(寵物是不會自己取名字的),你又不希望其他人能給你的寵物取名字。這時候友元機制就出來了。你可以在寵物類中指定主人類、你的摯友類為友元。隻讓他們可以拜訪寵物類的名字屬性。還有被重載的操作符,經常須要拜訪類的私有資料,這些操作又是類的成員。

            友元機制允許一個類将其所有成員的拜訪權授予指定的函數或類。友元的聲明以關鍵字friend開始,可以出現在類定義的任何地方。由于友元不是類的成員,是以不受類拜訪權限機制的影響,也不能通過類來拜訪友元(說了它不是類的成員)。

           友元函數(普通函數)

           1.友元函數不是類的成員,隻是一個有特别權限的全局函數。

           2.友元函數可以聲明在類的任何地方。

           3.友元函數的全部定義可以放在所拜訪類的定義中,這樣的友元函數默以為inline函數。

           4.友元函數在類外的定義不要帶關鍵字friend。

           5.友元函數必須有一個參數時要拜訪類的類型。因為友元函數不是類的成員,必須通過類對象.成員變量的方法來拜訪對象的成員變量。

#include <iostream>
using std::cout;
using std::endl;
class CBox // Class definition at global scope
{
public:
// Constructor definition
	explicit CBox(double lv = 1.0, double bv = 1.0, double hv = 1.0)
	{
		cout << endl << “Constructor called.”;
		m_Length = lv; // Set values of
		m_Width = bv; // data members
		m_Height = hv;
	}
// Function to calculate the volume of a box
	double Volume()
	{
		return m_Length*m_Width*m_Height;
	}
private:
	double m_Length; // Length of a box in inches
	double m_Width; // Width of a box in inches
	double m_Height; // Height of a box in inches
// Friend function
friend double BoxSurface(CBox aBox);
};
// friend function to calculate the surface area of a Box object
double BoxSurface(CBox aBox)
{
	return 2.0*(aBox.m_Length*aBox.m_Width +
	aBox.m_Length*aBox.m_Height +
	aBox.m_Height*aBox.m_Width);
}
int main()
{
	CBox box2; // Declare box2 - no initial values

	cout<< “Surface area of box2 = “<< BoxSurface(box2);
	cout << endl;
	return 0;
}      

    每日一道理

嶺上嬌豔的鮮花,怎敵她美麗的容顔?山間清澈的小溪,怎比她純潔的心靈?

       6.盡管對友元函數聲明在類中出現的位置沒有限制,當為了便于閱讀,類中所有友元函數的位置保持一緻。比如都放在public成員和private成員以後。

       指定其他類的成員函數成為友元

           和普通友元函數一樣,隻是在聲明的時候加上類作用域,指明友元函數所屬的類。 比如

    friend void A::func(Box&);

           指定其他類為友元         

           指定其他類為友元後,則該其他類的所有成員函數都可以可以拜訪授權類的所有成員。

    關于成員函數設為友元應注意的聲明問題

           指定A類的成員函數為B類的友元之前必須先看到A類的定義(注意不是聲明)。先定義A時,如果A的這個成員函數要用A類型作參數,則必須先在B類之前聲明A是一個類(比必要是定義)。

    上面是示範

#include <iostream>
using std::cout;
using std::endl;

class A
{
public:
	class B;       //聲明類B
	void func(B&);
};
void A::func(B&)
{//定義類A的成員函數func
}

class B
{
	friend void A::func(B&);
};


int main(void)
{
	return 0;
}      

    上面在類A的定義中在聲明了類B。要不然通不過編譯。而且A的成員函數func必須先定義,而且不能是内聯函數(這意味着不能在類的聲明中實作一個成員函數,必須在類定義中聲明,類外實作)。