作者:jicanmeng
时间:2014年11月30日
通常,类的私有成员和保护成员只能由类的成员函数来访问,类的对象和外部函数只能访问类的public成员。但是我们有时会有这样的需求:直接在类的某个外部函数funcA()中访问类的私有数据。如果我们在类中定义一个public类型的成员函数,那么funcA()就可以调用这个成员函数访问类的私有数据了,但同时别的外部函数如funcB()也能调用这个类的成员函数。我们的要求是只有funcA()能访问类的私有数据,别的函数则不可以。这种情况下,我们可以将funcA()函数声明为这个类的友元函数(friend function)。
一个类的友元函数在这个类中进行声明,前面需要添加C++关键字"friend"。从字面意义来看,一个类的友元函数就是这个类的朋友,可以访问类的public、protected和private类型的成员。
learncpp.com上面是这样描述的:
A friend function is a function that can access the private members of a class as though it were a member of that class. In all other regards, the friend function is just like a normal function. A friend function may or may not be a member of another class. To declare a friend function, simply use the friend keyword in front of the prototype of the function you wish to be a friend of the class. It does not matter whether you declare the friend function in the private or public section of the class.
看一个示例程序:
#include <iostream> class Value { private: int m_nValue; public: Value(int nValue) { m_nValue = nValue; } friend bool IsEqual(const Value &cValue1, const Value &cValue2); }; bool IsEqual(const Value &cValue1, const Value &cValue2) { return (cValue1.m_nValue == cValue2.m_nValue); } int main() { Value cValue1(1); Value cValue2(2); std::cout << (IsEqual(cValue1, cValue2)?"equal":"not equal") << std::endl; return 0; }
几点说明:
一个函数可以同时是多个类的友元函数。如下面的程序:
#include <iostream> class Humidity; class Temperature { private: int m_nTemp; public: Temperature(int nTemp) { m_nTemp = nTemp; } friend void PrintWeather(Temperature &cTemperature, Humidity &cHumidity); }; class Humidity { private: int m_nHumidity; public: Humidity(int nHumidity) { m_nHumidity = nHumidity; } friend void PrintWeather(Temperature &cTemperature, Humidity &cHumidity); }; void PrintWeather(Temperature &cTemperature, Humidity &cHumidity) { std::cout << "The temperature is " << cTemperature.m_nTemp << " and the humidity is " << cHumidity.m_nHumidity << std::endl; } int main() { Temperature cTemperature(25); Humidity cHumidity(30); PrintWeather(cTemperature, cHumidity); return 0; }
一个类的友元函数可以是其它类的成员函数。将上面的程序修改一下:
#include <iostream> class Humidity; class Temperature { private: int m_nTemp; public: Temperature(int nTemp) { m_nTemp = nTemp; } void PrintWeather(Humidity &cHumidity); }; class Humidity { private: int m_nHumidity; public: Humidity(int nHumidity) { m_nHumidity = nHumidity; } friend void Temperature::PrintWeather(Humidity &cHumidity); }; void Temperature::PrintWeather(Humidity &cHumidity) { std::cout << "The temperature is " << m_nTemp << " and the humidity is " << cHumidity.m_nHumidity << std::endl; } int main() { Temperature cTemperature(25); Humidity cHumidity(30); cTemperature.PrintWeather(cHumidity); return 0; }
更进一步,我们可以将一个类声明为另外一个类的友元类。假设类ClassA为ClassB的友元类,那么ClassA中的所有成员函数都是ClassB的友元函数(这句话的意思是,ClassA的所有成员函数的参数中如果有Class &
类型的变量,那么该成员函数就是ClassB的友元函数。)
示例程序如下:
#include <iostream> class Storage { private: int m_nValue; double m_dValue; public: Storage(int nValue, double dValue) { m_nValue = nValue; m_dValue = dValue; } // Make the Display class a friend of Storage friend class Display; }; class Display { private: bool m_bDisplayIntFirst; public: Display(bool bDisplayIntFirst) { m_bDisplayIntFirst = bDisplayIntFirst; } void DisplayItem(Storage &cStorage) { if (m_bDisplayIntFirst) std::cout << cStorage.m_nValue << " " << cStorage.m_dValue << std::endl; else // display double first std::cout << cStorage.m_dValue << " " << cStorage.m_nValue << std::endl; } }; int main() { Storage cStorage(5, 6.7); Display cDisplay(false); cDisplay.DisplayItem(cStorage); return 0; }