本文地址: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
{
};
注意:
①友元不具備傳遞性!
②友元關系單向的!
③友元關系破壞了信息隱蔽的原則,但友元關系也提供了數據共享的一種方法。
④友元不受訪問限定符限制。