7. C++友元函數(shù)和友元類

7.1 友元函數(shù)

C++只有本類中的函數(shù)可以訪問(wèn)本類的 private 成員。

但一種情況例外,那就是友元(friend)。友元可以使得其他類中的成員函數(shù)以及全局范圍內(nèi)的函數(shù)訪問(wèn)當(dāng)前類的 private 成員。

在當(dāng)前類以外定義的,不屬于當(dāng)前類的函數(shù)也可以在當(dāng)前類中聲明,但要在前面加 friend 關(guān)鍵字,這樣的函數(shù)就是友元函數(shù)。

注意:友元函數(shù)可以是不屬于任何類的非成員函數(shù),也可以是其他類的成員函數(shù)。

友元函數(shù)可以訪問(wèn)當(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<<",成績(jī)是 "<<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;
}
image.png

注意:在友元函數(shù)中不能直接訪問(wèn)類的成員,必須要借助對(duì)象。

類的成員函數(shù)可以通過(guò)this指針完成屬性的調(diào)用,但是友元函數(shù)無(wú)法使用this,所以在該函數(shù)內(nèi)部需要為其傳遞一個(gè)對(duì)象的參數(shù),用來(lái)調(diào)用屬性,形參可以直接傳遞對(duì)象,也可以傳遞對(duì)象指針或?qū)ο笠谩?/p>


7.2 將其他類的成員函數(shù)聲明為友元函數(shù)

友元函數(shù)不僅可以是全局函數(shù)(非成員函數(shù)),還可以是另外一個(gè)類的成員函數(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<<",成績(jī)是 "<<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("遼寧", "沈陽(yáng)", "渾南");
    stu.show(&addr);
    Student *ps = new Student("呵呵", 17, 90.0);
    Address *paddr = new Address("遼寧", "大連", "甘井子");
    ps->show(paddr);
    return 0;
}
image.png

注意:一個(gè)函數(shù)可以被多個(gè)類聲明為友元函數(shù),這樣就可以訪問(wèn)多個(gè)類中的 private 成員。


7.3 友元類

我們呢還可以將整個(gè)類聲明為另一個(gè)類的友元類,這樣友元類中的所有成員函數(shù)都是另外一個(gè)類的友元函數(shù)。

例如將類 B 聲明為類 A 的友元類,那么類 B 中的所有成員函數(shù)都是類 A 的友元函數(shù),可以訪問(wèn)類 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ù),友元類極少使用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容