C++语言基础(15)-友元函数和友元类
?
一個類中可以有 public、protected、private 三種屬性的成員,通過對象可以訪問 public 成員,只有本類中的函數可以訪問本類的 private 成員。現在,我們來介紹一種例外情況——友元(friend)。借助友元(friend),可以使得其他類中的成員函數以及全局范圍內的函數訪問當前類的 private 成員。
一.將全局函數聲明為友元函數
例:
#include <iostream> using namespace std;class Student{ public:Student(char *name, int age, float score); public:friend void show(Student *pstu); //將show()聲明為友元函數 private:char *m_name;int m_age;float m_score; };Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }// 全局函數 void show(Student *pstu){cout<<pstu->m_name<<"的年齡是 "<<pstu->m_age<<",成績是 "<<pstu->m_score<<endl; }int main(){Student stu("小明", 15, 90.6);show(&stu); //調用友元函數Student *pstu = new Student("李磊", 16, 80.5);show(pstu); //調用友元函數return 0; }運行結果:
小明的年齡是 15,成績是 90.6
李磊的年齡是 16,成績是 80.5
注意:友元函數不同于類的成員函數,在友元函數中不能直接訪問類的成員,必須要借助對象。下面的寫法是錯誤的:
void show(){cout<<m_name<<"的年齡是 "<<m_age<<",成績是 "<<m_score<<endl; }二.將其它類的成員函數聲明為友元函數
#include <iostream> using namespace std;class Address; //提前聲明Address類//聲明Student類 class Student{ public:Student(char *name, int age, float score); public:void show(Address *addr); private:char *m_name;int m_age;float m_score; };//聲明Address類 class Address{ private:char *m_province; //省份char *m_city; //城市char *m_district; //區(市區) public:Address(char *province, char *city, char *district);//將Student類中的成員函數show()聲明為友元函數friend void Student::show(Address *addr); };//實現Student類 Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ } void Student::show(Address *addr){cout<<m_name<<"的年齡是 "<<m_age<<",成績是 "<<m_score<<endl;cout<<"家庭住址:"<<addr->m_province<<"省"<<addr->m_city<<"市"<<addr->m_district<<"區"<<endl; }//實現Address類 Address::Address(char *province, char *city, char *district){m_province = province;m_city = city;m_district = district; }int main(){Student stu("小明", 16, 95.5f);Address addr("陜西", "西安", "雁塔");stu.show(&addr);Student *pstu = new Student("李磊", 16, 80.5);Address *paddr = new Address("河北", "衡水", "桃城");pstu -> show(paddr);return 0; }運行結果:
小明的年齡是 16,成績是 95.5
家庭住址:陜西省西安市雁塔區
李磊的年齡是 16,成績是 80.5
家庭住址:河北省衡水市桃城區
注意:
1.程序剛開始對Address類進行提前聲明的意義在于:在Address類定義之前,在Student類中使用了它,如果不提前聲明,編譯器會報錯:'Address' has not been declared'
2.程序將 Student 類的聲明和實現分開了,而將 Address 類的聲明放在了中間,這是因為編譯器從上到下編譯代碼,show() 函數體中用到了 Address 的成員 province、city、district,如果提前不知道 Address 的具體聲明內容,就不能確定 Address 是否擁有該成員(類的聲明中指明了類有哪些成員)。
3.類的提前聲明的使用范圍是有限的,只有在正式聲明一個類以后才能用它去創建對象。如果在上面程序的第4行之后增加如下所示的一條語句,編譯器就會報錯:
Address addr; //企圖使用不完整的類來創建對象4.?一個函數可以被多個類聲明為友元函數,這樣就可以訪問多個類中的 private 成員。
三.友元類
可以將整個類聲明為友元類,這樣友元類中的所有成員函數都是另一個類的友元函數。
修改上述代碼:
#include <iostream> using namespace std;class Address; //提前聲明Address類//聲明Student類 class Student{ public:Student(char *name, int age, float score); public:void show(Address *addr); private:char *m_name;int m_age;float m_score; };//聲明Address類 class Address{ public:Address(char *province, char *city, char *district); public://將Student類聲明為Address類的友元類friend class Student; private:char *m_province; //省份char *m_city; //城市char *m_district; //區(市區) };//實現Student類 Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ } void Student::show(Address *addr){cout<<m_name<<"的年齡是 "<<m_age<<",成績是 "<<m_score<<endl;cout<<"家庭住址:"<<addr->m_province<<"省"<<addr->m_city<<"市"<<addr->m_district<<"區"<<endl; }//實現Address類 Address::Address(char *province, char *city, char *district){m_province = province;m_city = city;m_district = district; }int main(){Student stu("小明", 16, 95.5f);Address addr("陜西", "西安", "雁塔");stu.show(&addr);Student *pstu = new Student("李磊", 16, 80.5);Address *paddr = new Address("河北", "衡水", "桃城");pstu -> show(paddr);return 0; }將Student類聲明為Address類的友元類的語句為:
friend class Student;有的編譯器也可以不寫 class 關鍵字,不過為了增強兼容性還是建議寫上。
注意:
1.友元的關系是單向的而不是雙向的。如果聲明了類 B 是類 A?的友元類,不等于類 A 是類 B?的友元類,類 A?中的成員函數不能訪問類 B 中的 private 成員。
2.友元的關系不能傳遞。如果類 B 是類 A 的友元類,類 C 是類 B 的友元類,不等于類 C 是類 A 的友元類。
?
總結
以上是生活随笔為你收集整理的C++语言基础(15)-友元函数和友元类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bzoj1833: [ZJOI2010]
- 下一篇: QTP的那些事---通过html标签的属