??????????????????????創做不易,麻煩點個關注????????????????????????
??????????????????文末有驚喜!獻舞一支!????????????????????
目錄
9.12 C++之友元函數
9.12.1 友元函數的聲明friend
9.12.2 普通全局函數作為類的友元函數
9.12.3 類的某個成員函數作為另外一個類的友元函數
9.12.4 整個類作為另外一個類的友元
點贊👍? + 收藏👐 + 關注👌
9.12 C++之友元函數
問題:什么是友元函數?
????????在 C++ 中,友元函數是指在一個類的外部定義的、被該類聲明為友元的非成員函數。友元函數可以訪問該類的所有成員(包括私有成員),并且可以在不通過類對象進行訪問的情況下改變成員的值。
? ? ? ? 類的擁有不同權限訪問函數的一個主要特點,即類的私有成員無法在類的外部(作用域之外)訪問。但是,我們上一小節文章末尾留下了一個疑惑,在有時候需要在類的外部訪問類的私有成員怎么辦?
????????解決方法是使用友元函數,友元函數是一種特權函數,C++允許這個特權函數訪問私有成員。這一點從現實生活中也可以很好的理解。比如你的錢是你個人私有的,你家里人拿你的錢你是可以允許的,但是一個陌生人來拿你的錢,你就不能直接給他了。這時候你家人出來一個說這是他的律師來,是他的朋友,拿了一個東西證明了這個關系(friend == 合法合同、或者律師證,或者你的電話,或者你本人,用來證明你們朋友關系的紐帶),這樣就可以把你個人的錢給他了。我們可以把一個全局函數、某個類中的成員函數、甚至整個類聲明為友元。
? ? ?(👮👮👮這里提醒大家,不要輕易給陌生人轉賬、發紅包、匯款等,任何!所有!一切!讓你先轉賬才可以得到什么的理由!!!都是詐騙!!!并且不是通過購物平臺或者官方的平臺的,私人的那種,而且交易方式沒有實名等!都是騙子!警惕詐騙,轉賬之前一定要確認對方是否是你認識的人,或者是你的家人等等。警防網絡詐騙,讓騙子無處可騙。防詐騙從每個人做起👮👮👮)
? ? ? ? 特別的:友元函數會破壞類的封裝性😭,因為私有數據可以被外部訪問到
9.12.1 友元函數的聲明friend
????????友元函數使用friend關鍵字聲明一個函數為友元函數。
? ? ? ? friend關鍵字只使用于聲明處,一個函數或者是類對象作為另外一個類的友元,例如A類作為B類的友元,那么A類可以直接訪問B類中的私有數據。
? ? ? ? 友元比較著重運用在運算符重載上。
9.12.2 普通全局函數作為類的友元函數
這里我們使用了一個案例舉例:是在千鋒教育C++嵌入式基礎班講解(后續案例用qf縮寫代替)的一個案例:例如你的家,有客廳,有你的臥室,那么你的客廳是Public的,所有來的客人都可以進去,但是你的臥室是私有的,也就是說只有你能進去,但是呢,你也可以允許你的好閨蜜、好基友進去參觀你的臥室(基于正常情況,防止杠精)。
1.當不是友元的時候,訪問私有成員會報錯的
當使用相同名字的時候,聲明為友元函數的時候,公共函數visitingfun()就沒有報錯。?
完整案例+結果
代碼:
#include <iostream>
#include <string>
using namespace std;class Room
{friend void visitingfun(Room &room);
private:string bedRoom;//臥室public:
public:string setingRoom;//客廳pubTic:
public:Room(string bedRoom, string setingRoom){this->bedRoom = bedRoom;this->setingRoom = setingRoom;}
};
//普通全局函數
void visitingfun(Room &room){cout<<"訪問了"<<room.setingRoom<<endl;cout<<"訪問了"<<room.bedRoom<<endl;
}
void test01(){Room room("私人豪華大床房臥室","公共188大平層客廳");visitingfun(room);
}
int main()
{test01();return 0;
}
9.12.3 類的某個成員函數作為另外一個類的友元函數
這個案例中,goodfriens類中的vistinng_02成員函數作為Room1類的友元函數。此時就是不同類的成員,進行一個私有成員變量的訪問。
拓展:
?上面的案例中,成員函數聲明和定義順序比較關鍵,總所周知,程序是向下編譯的,順序執行。
那看下面這個圖片中:成員函數放到類對象里,此時報錯原因,即使你提前聲明了Room1,但是由于初始化階段,還沒有生成Room1的成員,此時編譯器是不知道Room1里面有什么成員的。所以此時報錯了。
另外,goodfriends的聲明也應該在Room1聲明之前(這里僅僅針對9.12.3主題來說,因為你要的是成員函數)?,編譯器提前聲明只是知道了一個名字,編譯順序始終是從上往下執行的。
所以,你要把類中要成為友元函數的成員函數,定義實現放在外面,放在所有類的聲明的后面就行了。
9.12.4 整個類作為另外一個類的友元
????????就是這個類的所有成員函數都可以訪問另一個類的私有數據。
并且,聲明的順序可成員函數的基本一致。
?代碼:
class Room1;//向前聲明方式,這樣只能說明類的名稱
class goodfrieds
{
public:void visiting_01(Room1 &room);void visiting_02(Room1 &room);};
class Room1{//friend void goodfrieds::visiting_02(Room1 &room);friend class goodfrieds;
private:string bedRoom;//臥室public:
public:string setingRoom;//客廳pubTic:
public:Room1(string bedRoom, string setingRoom){this->bedRoom = bedRoom;this->setingRoom = setingRoom;}
};
void goodfrieds::visiting_01(Room1 &room){cout<<"訪問了01"<<room.setingRoom<<endl;cout<<"訪問了01"<<room.bedRoom<<endl;
}
void goodfrieds::visiting_02(Room1 &room){cout<<"訪問了02"<<room.bedRoom<<endl;cout<<"訪問了02"<<room.setingRoom<<endl;
}
void test03(){Room1 room("私人豪華大床房臥室","公共188大平層客廳");goodfrieds ob;ob.visiting_01(room);ob.visiting_02(room);
}
int main()
{test03();return 0;
}
點贊👍? + 收藏👐 + 關注👌
??您的支持??是我最大的動力??相互學習??共同進步??一起搞錢??動動發財的小手??
? ????????????????????十星好評,Erike的專用模板????????????????????
謝? ? ?謝? ? ?老? ? ?板!老? ? ?板? ? ?大? ? ?氣!