C++簡單又輕松的講解類和對象中友元函數
友元
用到關鍵字 friend
淺解概念
舉一個非常實際的例子,假如端午節到瞭你煮瞭兩種粽子,一種是普通的糯米粽子,一種是特殊的五花肉粽子,糯米粽隻要是客人都可以品嘗,而五花肉棕隻限好朋友品嘗,這時候就可以用到友元的知識瞭。在程序裡,有些私有屬性也想讓類外特殊的一些函數或者類訪問,就要用到友元函數。
友元目的
讓一個函數或者類,訪問另一個類的私有屬性
友元的三種實現
全局函數、成員函數、類都可以做友元。
全局函數做友元
示例:
class Host //東傢 { friend void FriendFunc(Host& H); private: string m_Precious; public: string m_Common; Host() :m_Precious("五花肉粽"), m_Common("糯米粽") {} }; void VisitFunc(Host &H) { cout << "你的 客人可以吃到你的:" << H.m_Common << endl; } void FriendFunc(Host &H) { cout << "你的好朋友可以吃到你的:" << H.m_Precious <<"和"<<H.m_Common<< endl; }
運行效果:
普通客人函數沒有權限訪問Host類的私有屬性m_Precious ,而好朋友函數在類中加上friend關鍵字聲明就可以訪問類內所有成員屬性。最好寫到類最上面,這樣可以在第一時間告訴編譯器該全局函數是該類的友元函數。
類做友元
示例:
class Host //東傢 類 { friend class FriendFunc; private: string m_Precious; public: string m_Common; Host() :m_Precious("五花肉粽"), m_Common("糯米粽") {} }; class FriendFunc //好朋友類 { public: Host* host; void visit(); FriendFunc(); }; void FriendFunc::visit() { cout << "你的好朋友可以吃到你的:" << host->m_Precious << "和" << host->m_Common << endl; } FriendFunc::FriendFunc() { host = new Host; } void test01() { FriendFunc F; F.visit(); } int main() { test01(); }
運行效果:
首先直接copy下來全局函數做友元的Host類,然後把上面的FriendFunc函數變為類;同樣在Host類中聲明FirstFunc類是其友元類,然後給友元類定義Host類指針,vist訪問方法和默認構造函數,這裡方法和函數均在類內定義,類外聲明;註意:構造函數的聲明不需要返回值類型。
友元類的構造函數定義中直接new瞭一個Host類,當我們調用友元類的默認構造同時調用Host的默認構造函數並通過初始化列表完成自動賦值,這樣就可以在visit函數中訪問Host類的成員屬性瞭。使用指針的原因就是new的返回值為指針類型,在堆區開辟空間。
成員函數做友元
示例:
#include<iostream> using namespace std; class Host; class FriendFun//好朋友類 { public: FriendFun(); Host* host; void visit(); //讓其可以訪問Host類的私有成員 void visit0(); //和visit對比,不能訪問Host類私有成員 }; class Host //東傢 類 { friend void FriendFun::visit(); private: string m_Precious; public: string m_Common; Host() :m_Precious("五花肉粽"), m_Common("糯米粽") {} }; FriendFun::FriendFun() { host = new Host; } void FriendFun::visit() //讓其可以訪問Host類的私有成員 { cout << "你的好朋友可以吃到你的:" << host->m_Precious << "和" << host->m_Common << endl; } void FriendFun::visit0() //和visit對比,不能訪問Host類私有成員 { cout << "你的好朋友可以吃到你的:" << host->m_Common << endl; } void test() { FriendFun F; F.visit(); F.visit0(); } int main() { test(); }
運行效果:
成員函數作為友元和全局函數作為友元區別就是函數聲明的位置不同,同樣在Host類裡加上friend關鍵字即可,但是一定要註意函數或者方法聲明後定義的位置,死死記住代碼是按照順序執行的。
註意事項
舉個例子:如果直接類內定義FriendFun的構造函數,程序會提示你未定義類型Host,為什麼呢,我明明在Host類之前聲明瞭啊,確實聲明瞭,也定義瞭啊,但是編譯器來不及看到定義就以及執行瞭new Host,肯定會報錯;按正確的寫法就是把構造函數定義寫在Host定義之後,這樣程序就把定義的Host看完瞭,就可以自然而然的生成新的成員瞭;其實visit的定義也必須寫在調用FriendFun構造函數之後,因為隻有構造生成瞭新成員,才能訪問到公共或者私有屬性啊!
總結
學習完這篇快點去定義誰才能獲取你五花肉粽子的特權吧,挺有意思的。總體來說友元這塊知識不難,但是一定要註意細節,我在總結這裡再說一次,代碼一定是按照順序執行的,類內外定義一定要註意順序,還記得這段知識點,一個bug卡瞭我兩個小時,希望你們能避開我的坑,順利前行
到此這篇關於C++簡單又輕松的講解類和對象中友元函數的文章就介紹到這瞭,更多相關C++友元函數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!