7.1 友元函數(shù)
C++只有本類中的函數(shù)可以訪問本類的 private 成員。
但一種情況例外,那就是友元(friend)逸邦。友元可以使得其他類中的成員函數(shù)以及全局范圍內(nèi)的函數(shù)訪問當(dāng)前類的 private 成員。
在當(dāng)前類以外定義的,不屬于當(dāng)前類的函數(shù)也可以在當(dāng)前類中聲明捐腿,但要在前面加 friend 關(guān)鍵字,這樣的函數(shù)就是友元函數(shù)柿顶。
注意:友元函數(shù)可以是不屬于任何類的非成員函數(shù)茄袖,也可以是其他類的成員函數(shù)。
友元函數(shù)可以訪問當(dāng)前類中的所有成員(包括 public九串、protected绞佩、private修飾的成員)。
1猪钮、將非成員函數(shù)聲明為友元函數(shù)品山。
#include <iostream>
using namespace std;
class Student{
public:
Student(char *name, int age, float score);
public:
friend void show(Student *pstu); //將show()聲明為友元函數(shù)
private:
char *name;
int age;
float score;
};
Student::Student(char *name, int age, float score): name(name), age(age), score(score){ }
//非成員函數(shù)
void show(Student *ps){
cout<<ps->name<<"的年齡是 "<<ps->age<<",成績是 "<<ps->score<<endl;
}
int main(){
Student stu("豆豆", 18, 80.0);
show(&stu); //調(diào)用友元函數(shù)
Student *ps = new Student("呵呵", 17, 90.0);
show(ps); //調(diào)用友元函數(shù)
return 0;
}
注意:在友元函數(shù)中不能直接訪問類的成員烤低,必須要借助對象肘交。
類的成員函數(shù)可以通過this指針完成屬性的調(diào)用,但是友元函數(shù)無法使用this扑馁,所以在該函數(shù)內(nèi)部需要為其傳遞一個對象的參數(shù)涯呻,用來調(diào)用屬性凉驻,形參可以直接傳遞對象,也可以傳遞對象指針或?qū)ο笠谩?/p>
7.2 將其他類的成員函數(shù)聲明為友元函數(shù)
友元函數(shù)不僅可以是全局函數(shù)(非成員函數(shù))复罐,還可以是另外一個類的成員函數(shù)涝登。
#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 *name;
int age;
float score;
};
//聲明Address類
class Address{
private:
char *province; //省份
char *city; //城市
char *district; //區(qū)(市區(qū))
public:
Address(char *province, char *city, char *district);
//將Student類中的成員函數(shù)show()聲明為友元函數(shù)
friend void Student::show(Address *addr);
};
//實(shí)現(xiàn)Student類
Student::Student(char *name, int age, float score): name(name), age(age), score(score){ }
void Student::show(Address *addr){
cout<<name<<"的年齡是 "<<age<<",成績是 "<<score<<endl;
cout<<"家庭住址:"<<addr->province<<"省"<<addr->city<<"市"<<addr->district<<"區(qū)"<<endl;
}
//實(shí)現(xiàn)Address類
Address::Address(char *province, char *city, char *district){
this->province = province;
this->city = city;
this->district = district;
}
int main(){
Student stu("豆豆", 18, 80.0);
Address addr("遼寧", "沈陽", "渾南");
stu.show(&addr);
Student *ps = new Student("呵呵", 17, 90.0);
Address *paddr = new Address("遼寧", "大連", "甘井子");
ps->show(paddr);
return 0;
}
注意:一個函數(shù)可以被多個類聲明為友元函數(shù)效诅,這樣就可以訪問多個類中的 private 成員胀滚。
7.3 友元類
我們呢還可以將整個類聲明為另一個類的友元類,這樣友元類中的所有成員函數(shù)都是另外一個類的友元函數(shù)乱投。
例如將類 B 聲明為類 A 的友元類咽笼,那么類 B 中的所有成員函數(shù)都是類 A 的友元函數(shù),可以訪問類 A 的所有成員戚炫,包括 public剑刑、protected、private 屬性的双肤。
將Student類聲明為Address類的友元類施掏,在Address類中
public:
//將Student類聲明為Address類的友元類
friend class Student;
注意:
1、友元的關(guān)系是單向的杨伙。
類 B 是類 A 的友元類其监,不等于類 A 是類 B 的友元類。
2限匣、友元的關(guān)系不能傳遞抖苦。類 A 是類 B 的友元類,類 B 是類 C 的友元類米死,但類 A不是類 C 的友元類(朋友的朋友不一定也是朋友)锌历。
3、為了數(shù)據(jù)的安全性峦筒,一般我們只聲明友元函數(shù)究西,友元類極少使用。