friend class

提到友元類,一般會同時提到友元函式。兩者在許可權開放上類似。

採用類的機制後實現了數據的隱藏與封裝,類的數據成員一般定義為私有成員,成員函式一般定義為公有的,依此提供類與外界間的通信接口。但是,有時需要定義一些函式,這些函式不是類的一部分(注意友元函式不是類的一部分),但又需要頻繁地訪問類的數據成員,這時可以將這些函式定義為該函式的友元函式。除了友元函式外,還有友元類,兩者統稱為友元。友元的作用是提高了程式的運行效率(即減少了類型檢查和安全性檢查等都需要時間開銷),但它破壞了類的封裝性和隱藏性,使得非成員函式可以訪問類的私有成員。

友元函式,1.1將全局函式聲明為友元函式,1.2友元成員函式,1.3關於類的提前引用聲明,1.4將一個函式聲明為多個類的友元函式,友元類,
友元函式與友元類。
C++中以關鍵字friend聲明友元關係。友元可以訪問與其有friend關係的類中的私有成員。友元包括友元函式和友元類。

友元函式

如果在本類以外的其它地方定義了一個函式(這個函式可以是不屬於任何類的非成員函式,也可以是其它類的成員函式),在類體中用friend對該函式進行聲明,此函式就稱為本類的友元函式。一個類的友元函式可以訪問這個類中的private成員。

1.1將全局函式聲明為友元函式

如果要將一個全局函式(call)聲明為本類(Time)的友元函式,則只需要在本類的函式聲明部分聲明該函式為friend。此時,該函式可以訪問本類的private成員。
class Time{
public:
Time(int=1,int=1,int=1);
friendvoid call(Time &);//聲明友元函式
private:
int hour;
int min;
int sec;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
void call(Time &t) {//全局函式,且是Time類的友元函式
cout<<"Call:"<<t.hour<<"-"<<t.min<<"-"<<t.sec<<endl;//訪問private成員
}
int main(){
Time t;
call(t);
system("PAUSE");
return EXIT_SUCCESS;
}

1.2友元成員函式

如果需要將目標類(Time)中的成員函式(call)聲明為本類(Date)的友元函式,則需要在本類的函式聲明部分聲明該函式為friend。此時,該函式可以訪問本類的private成員。
class Date; //對Date類的提前引用聲明
class Time{
public:
Time(int=1,int=1,int=1);
void call(Date &);//聲明成員函式
private:
int hour;
int min;
int sec;
};
class Date{
public:
Date(int=1,int=1,int=2008);
friendvoid Time::call(Date&); //聲明Time類的call為本類的友元成員函式
private:
int year;
int mon;
int day;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
void Time::call(Date &d) {
cout<<"TIME:"<<hour<<"-"<<min<<"-"<<sec<<endl;
cout<<"DATE:"<<d.mon<<"-"<<d.day<<"-"<<d.year<<endl; //訪問Date類的private成員
}
Date::Date(int m,int d,int y){
mon=m;
day=d;
year=y;
}
int main(){
Time t;
Date d;
t.call(d);
system("PAUSE");
return EXIT_SUCCESS;
}
這裡還做了對類的提前引用聲明。

1.3關於類的提前引用聲明

一般情況下,類必須先聲明(給出類體),才能使用。如果需要在類聲明之前,使用該類的名字去定義指向該類對象的指針或引用,可以使用提前引用聲明。如上例所示,
class Date; //對Date類的提前引用聲明

void call(Date &);//Date類的引用

class Date{…}//Date類的聲明
但不能因為提前引用聲明,而去定義一個類的對象,這是不允許的。
class Date;
//緊接著馬上定義一個Date類的對象
Date d1;error:aggregate `Date d1' has incomplete type and cannot be defined

class Date{…}
在定義對象時要為這些對象分配存儲空間,在正式聲明類之前,編譯系統無法確定應為對象分配多大的存儲空 間。編譯系統只有見到“類體”之後才能確定應該為對象預留多大的空間。所以不能在聲明類之前,先定義一個該類的對象。但是可以在聲明類之前,先使用該類的 名字定義一個該類的指針或引用。因為指針變數和引用本身的大小是固定的,它與指向的類對象的大小無關。

1.4將一個函式聲明為多個類的友元函式

在這種情況下,該函式可以同時訪問多個類的private成員。
class Date; //對Date類的提前引用聲明
class Time{
public:
Time(int=1,int=1,int=1);
friendvoid call(Time&,Date&);//聲明函式call為本類的友元成員函式
private:
int hour;
int min;
int sec;
};
class Date{
public:
Date(int=1,int=1,int=2008);
friendvoid call(Time&,Date&); //聲明函式call為本類的友元成員函式
private:
int year;
int mon;
int day;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
Date::Date(int m,int d,int y){
mon=m;
day=d;
year=y;
}
void call(Time &t,Date &d) {
cout<<"TIME:"<<t.hour<<"-"<<t.min<<"-"<<t.sec<<endl;
cout<<"DATE:"<<d.mon<<"-"<<d.day<<"-"<<d.year<<endl;
}
int main(){
Time t;
Date d;
call(t,d);
system("PAUSE");
return EXIT_SUCCESS;
}

友元類

可以將一個類(B)聲明為當前類(A)的友元。此時,當前類(A)的友元類(B)中的所有成員函式都是當前類的友元函式,可以訪問當前類的private成員。
class Date; //對Date類的提前引用聲明
class Time{
public:
Time(int=1,int=1,int=1);
friendclass Date;//將Date類聲明為當前類的友元類
private:
int hour;
int min;
int sec;
};
class Date{
public:
Date(int=1,int=1,int=2008);
void call_hour(Time&);
void call_min(Time&);
void call_sec(Time&);
private:
int year;
int mon;
int day;
};
Time::Time(int h,int m,int s){
hour=h;
min=m;
sec=s;
}
Date::Date(int m,int d,int y){
mon=m;
day=d;
year=y;
}
void Date::call_hour(Time &t){
cout<<"HOUR:"<<t.hour<<endl;
}
void Date::call_min(Time &t){
cout<<"MINUTE:"<<t.min<<endl;
}
void Date::call_sec(Time &t){
cout<<"SECOND:"<<t.sec<<endl;
}
int main(){
Time t;
Date d;
d.call_hour(t);
d.call_min(t);
d.call_sec(t);
system("PAUSE");
return EXIT_SUCCESS;
}

相關詞條

熱門詞條

聯絡我們