本文地址:http://www.cnblogs.com/archimedes/p/cpp-friend.html,轉載請注明源地址
回憶函數的原型聲明
#include <iostream> using std::cout; using std::endl; void test(); int main() { test(); return 0; } void test() { cout << "函數的提前聲明!" << endl; }
類和函數也是類似的,有時也需要提前聲明
class B; //提前聲明 class A { //class B }; int main() { void ff(B &); //RIGHT可以聲明引用 B *p_b = NULL; //RIGHT可以定義指針! //B bb; //ERROR不能定義對象 system("PAUSE"); return 0; } class B { }; void ff(B &) {}
注意:
提前聲明不能定義該類的對象
僅能定義該類的指針或引用
為何引入友元?
通常一個類中的非公有成員是無法被該類的非成員函數直接訪問的!如果我們將函數聲明為這個類的友元,該函數將能訪問該類的非公有成員!
概念:將類外的函數(頂層函數)聲明為友元函數
聲明方法:
friend 類型 函數名(形參表);
在類中用friend聲明函數!
#include <iostream> #include <string> using namespace std; class Time { public: Time(int aH=0, int aM=0, int aS=0); friend void display(Time&); private: int hour; int minute; int second; }; Time::Time(int aH, int aM, int aS) { hour=aH; minute=aM; second=aS; } void display(Time &t) { cout<<t.hour<<":"<<t.minute<<":"<<t.second<<endl; } int main() { Time t(12,30,54); display(t); system("PAUSE"); return 0; }
注意:
①友元函數應該聲明在類體內,且friend僅在聲明時使用,只出現一次。
②調用方式和普通全局函數一樣。
③友元全局函數的聲明語句就是函數的聲明語句。
④友元全局函數也可以在類內定義,此時編譯環境仍將其視為全局函數,且定義就相當於聲明而不需要提前聲明。
⑤一個全局函數可以被聲明為多個類的友元。
⑥多個全局函數可以被聲明為一個類的友元。
概念:一個類的成員函數可以被聲明為另一個類的友元。
聲明方法:
friend 類型 類名::函數名(形參表);
#include <iostream> #include <string> using namespace std; class Atest; //提前聲明 class Btest { public: Btest(int aX = 4):m_dVal(aX){} void display(Atest &aVal); private: double m_dVal; }; class Atest { public: Atest(int aX = 3):m_iVal(aX){} friend void Btest ::display(Atest &aVal); private: int m_iVal; }; void Btest::display(Atest &aVal) { cout << "Atest.m_iVal = " << aVal.m_iVal << endl; cout << "Btest.m_dVal = " << m_dVal << endl; } int main( ) { Atest testa; Btest testb; testb.display(testa); getchar( ); return 0; }
為什麼引入友元類?
如果一個類A中的成員函數都希望訪問類B的非公有成員,我們可以將A聲明為B類的友元類
聲明方法:
friend 類名;
class Date; class Person { friend Date;//在person類中的任意位置 }; class Date { };
注意:
①友元不具備傳遞性!
②友元關系單向的!
③友元關系破壞了信息隱蔽的原則,但友元關系也提供了數據共享的一種方法。
④友元不受訪問限定符限制。