複製鏈接
請複製以下鏈接發送給好友

friend class

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

friend class函數簡介

友元函數與友元類。
C++中以關鍵字friend聲明友元關係。友元可以訪問與其有friend關係的類中的私有成員。友元包括友元函數和友元類。

friend class友元函數

如果在本類以外的其它地方定義了一個函數(這個函數可以是不屬於任何類的非成員函數,也可以是其它類的成員函數),在類體中用friend對該函數進行聲明,此函數就稱為本類的友元函數。一個類的友元函數可以訪問這個類中的private成員。
1.1將全局函數聲明為友元函數
如果要將一個全局函數(call)聲明為本類(Time)的友元函數,則只需要在本類的函數聲明部分聲明該函數為friend。此時,該函數可以訪問本類的private成員。
class Time{
public:
Time(int=1,int=1,int=1);
friend void 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:"<
}
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
cout
}
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
cout
}
int main(){
Time t;
Date d;
call(t,d);
system("PAUSE");
return EXIT_SUCCESS;
}

friend class友元類

可以將一個類(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
}
void Date::call_min(Time &t){
cout
}
void Date::call_sec(Time &t){
cout
}
int main(){
Time t;
Date d;
d.call_hour(t);
d.call_min(t);
d.call_sec(t);
system("PAUSE");
return EXIT_SUCCESS;
}