扼要引見C++編程中的友元函數和友元類。本站提示廣大學習愛好者:(扼要引見C++編程中的友元函數和友元類)文章只能為提供參考,不一定能成為您想要的結果。以下是扼要引見C++編程中的友元函數和友元類正文
一個類中可以有 public、protected、private 三種屬性的成員,經由過程對象可以拜訪 public 成員,只要本類中的函數可以拜訪本類的 private 成員。如今,我們來彌補引見一個破例——友元(friend)。
fnend 的意思是同伙,或許說是石友,與石友的關系明顯要比普通人密切一些。有的家庭能夠會如許處置:客堂對一切來客開放,而臥室除本家庭的成員可以進人之外,還許可好同伙進入。在C++中,這類關系以症結宇 friend 聲明,中文多譯為友元。友元可以拜訪與其有石友關系的類中的公有成員,友元包含友元函數和友元類。假如您對友元這個名詞不習氣,可以按原文 friend 懂得為同伙便可。
友元函數
在以後類之外界說的、不屬於以後類的函數也能夠在類中聲明,但要在後面加 friend 症結字,如許就組成了友元函數。友元函數可所以不屬於任何類的非成員函數,也能夠是其他類的成員函數。
友元函數可以拜訪以後類中的一切成員,包含 private 屬性的。
1) 將通俗函數聲明為友元函數。
#include<iostream> using namespace std; class Student{ private: char *name; int age; float score; public: Student(char*, int, float); friend void display(Student &); //將display聲明為友元函數 }; Student::Student(char *name, int age, float score){ this->name = name; this->age= age; this->score = score; } //通俗成員函數 void display(Student &stu){ cout<<stu.name<<"的年紀是 "<<stu.age<<",成就是 "<<stu.score<<endl; } int main(){ Student stu("小明", 16, 95.5f); display(stu); return 0; }
運轉成果:
小明的年紀是 16,成就是 95.5
請留意 display 是一個在類外界說的且沒有應用 Student 作限制的函數,它長短成員函數,不屬於任何類,它的感化是輸入先生的信息。假如在 Student 類中未聲明 display 函數為 friend 函數,它是不克不及援用 Student 中的公有成員 name、age、score 的。年夜家可以親測一下,將下面法式中的第11行刪去,不雅察編譯時的信息。
如今因為聲清楚明了 display 是 Student 類的 friend 函數,所以 display 可使用 Student 中的公有成員 name、age、score。但留意在應用這些成員變量時必需加上對象名,不克不及寫成:
cout<<name<<"的年紀是 "<<age<<",成就是 "<<score<<endl;
由於 display 不是 Student 類的成員函數,默許不克不及應用 Student 類的成員,必需指定要拜訪的對象。
2) 將其他類的成員函數聲明為友元函數
friend 函數不只可所以通俗函數(非成員函數),還可所以另外一個類中的成員函數。請看上面的例子:
#include<iostream> using namespace std; class Address; //對Address類的提早援用聲明 //聲明Student類 class Student{ private: char *name; int age; float score; public: Student(char*, int, float); void display(Address &); }; //聲明Address類 class Address{ private: char *province; char *city; char *district; public: Address(char*, char*, char*); //將Student類中的成員函數display聲明為友元函數 friend void Student::display(Address &); }; Address::Address(char *province, char *city, char *district){ this->province = province; this->city = city; this->district = district; } //聲明Student類成結構函數和成員函數 Student::Student(char *name, int age, float score){ this->name = name; this->age= age; this->score = score; } void Student::display(Address &add){ cout<<name<<"的年紀是 "<<age<<",成就是 "<<score<<endl; cout<<"家庭住址:"<<add.province<<"省"<<add.city<<"市"<<add.district<<"區"<<endl; } int main(){ Student stu("小明", 16, 95.5f); Address add("陝西", "西安", "雁塔"); stu.display(add); return 0; }
運轉成果:
小明的年紀是 16,成就是 95.5 家庭住址:陝西省西安市雁塔區
在本例中界說了兩個類 Student 和 Address。法式第 26 即將 Student 類中的成員函數 display 聲明為友元函數,由此,display 便可以拜訪 Address 類的公有成員變量了。
兩點留意:
① 法式第4行對Address類停止了提早聲明,是由於在Address類界說之前、在Student類中應用到了它,假如不提早聲明,編譯會報錯,提醒"Address" has not been declared。類的提早聲明和函數的提早聲明是一個事理。
② 法式中將 Student 類的聲明和界說離開了,而將 Address 放在了中央,是由於 Student::display() 函數體頂用到了 Address 類的成員,必需湧現在 Address 類的類體以後(類體解釋了有哪些成員)。
這裡簡略引見一下類的提早聲明。普通情形下,類必需在正式聲明以後能力應用;然則某些情形下(如上例所示),只需做好提早聲明,也能夠先應用。
然則應該留意,類的提早聲明的應用規模是無限的。只要在正式聲明一個類今後能力用它去創立對象。假如在下面法式第4行前面增長一行:
Address obj; //妄圖界說一個對象
會在編譯時失足。由於創立對象時是要為對象分派內存空間的,在正式聲明類之前,編譯體系沒法肯定應當為對象分派多年夜的空間。編譯器只要在“見到”類體後(實際上是見到成員變量),能力肯定應當為對象預留多年夜的空間。在對一個類作了提早援用聲明後,可以用該類的名字去界說指向該類型對象的指針變量或對象的援用變量(如在本例中,界說了Address類對象的援用變量)。這是由於指針變量和援用變量自己的年夜小是固定的,與它所指向的類對象的年夜小有關。
請留意法式是在界說 Student::display() 函數之前正式聲明 Address 類的。這是由於在 Student::display() 函數體中要用到 Address 類的成員變量 province、city、district,假如不正式聲明 Address 類,編譯器就沒法辨認這些成員變量。
③ 一個函數可以被多個類聲明為“同伙”,如許便可以援用多個類中的公有成員。
友元類
不只可以將一個函數聲明為一個類的“同伙”,並且可以將全部類(例如B類)聲明為另外一個類(例如A類)的“同伙”。這時候B類就是A類的友元類。
友元類B中的一切函數都是A類的友元函數,可以拜訪A類中的一切成員。在A類的類體頂用以下語句聲明B類為其友元類:
friend B;
聲明友元類的普通情勢為:
friend 類名;
關於友元,有兩點須要解釋:
友元的關系是單向的而不是雙向的。假如聲清楚明了 B類是A類的友元類,不等於A類是B類的友元類,A類中的成員函數不克不及拜訪B類中的公有數據。
友元的關系不克不及傳遞,假如B類是A類的友元類,C類是B類的友元類,不等於 C類是A類的友元類。
在現實開辟中,除非確有需要,普通其實不把全部類聲明為友元類,而只將確切有須要的成員函數聲明為友元函數,如許更平安一些。