C++簡單又輕松的講解類和對象中友元函數(shù)
友元
用到關(guān)鍵字 friend
淺解概念
舉一個(gè)非常實(shí)際的例子,假如端午節(jié)到了你煮了兩種粽子,一種是普通的糯米粽子,一種是特殊的五花肉粽子,糯米粽只要是客人都可以品嘗,而五花肉棕只限好朋友品嘗,這時(shí)候就可以用到友元的知識(shí)了。在程序里,有些私有屬性也想讓類外特殊的一些函數(shù)或者類訪問,就要用到友元函數(shù)。
友元目的
讓一個(gè)函數(shù)或者類,訪問另一個(gè)類的私有屬性
友元的三種實(shí)現(xiàn)
全局函數(shù)、成員函數(shù)、類都可以做友元。
全局函數(shù)做友元
示例:
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; }
運(yùn)行效果:
普通客人函數(shù)沒有權(quán)限訪問Host類的私有屬性m_Precious ,而好朋友函數(shù)在類中加上friend關(guān)鍵字聲明就可以訪問類內(nèi)所有成員屬性。最好寫到類最上面,這樣可以在第一時(shí)間告訴編譯器該全局函數(shù)是該類的友元函數(shù)。
類做友元
示例:
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(); }
運(yùn)行效果:
首先直接copy下來全局函數(shù)做友元的Host類,然后把上面的FriendFunc函數(shù)變?yōu)轭悾煌瑯釉贖ost類中聲明FirstFunc類是其友元類,然后給友元類定義Host類指針,vist訪問方法和默認(rèn)構(gòu)造函數(shù),這里方法和函數(shù)均在類內(nèi)定義,類外聲明;注意:構(gòu)造函數(shù)的聲明不需要返回值類型。
友元類的構(gòu)造函數(shù)定義中直接new了一個(gè)Host類,當(dāng)我們調(diào)用友元類的默認(rèn)構(gòu)造同時(shí)調(diào)用Host的默認(rèn)構(gòu)造函數(shù)并通過初始化列表完成自動(dòng)賦值,這樣就可以在visit函數(shù)中訪問Host類的成員屬性了。使用指針的原因就是new的返回值為指針類型,在堆區(qū)開辟空間。
成員函數(shù)做友元
示例:
#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(); }
運(yùn)行效果:
成員函數(shù)作為友元和全局函數(shù)作為友元區(qū)別就是函數(shù)聲明的位置不同,同樣在Host類里加上friend關(guān)鍵字即可,但是一定要注意函數(shù)或者方法聲明后定義的位置,死死記住代碼是按照順序執(zhí)行的。
注意事項(xiàng)
舉個(gè)例子:如果直接類內(nèi)定義FriendFun的構(gòu)造函數(shù),程序會(huì)提示你未定義類型Host,為什么呢,我明明在Host類之前聲明了啊,確實(shí)聲明了,也定義了啊,但是編譯器來不及看到定義就以及執(zhí)行了new Host,肯定會(huì)報(bào)錯(cuò);按正確的寫法就是把構(gòu)造函數(shù)定義寫在Host定義之后,這樣程序就把定義的Host看完了,就可以自然而然的生成新的成員了;其實(shí)visit的定義也必須寫在調(diào)用FriendFun構(gòu)造函數(shù)之后,因?yàn)橹挥袠?gòu)造生成了新成員,才能訪問到公共或者私有屬性??!
總結(jié)
學(xué)習(xí)完這篇快點(diǎn)去定義誰才能獲取你五花肉粽子的特權(quán)吧,挺有意思的??傮w來說友元這塊知識(shí)不難,但是一定要注意細(xì)節(jié),我在總結(jié)這里再說一次,代碼一定是按照順序執(zhí)行的,類內(nèi)外定義一定要注意順序,還記得這段知識(shí)點(diǎn),一個(gè)bug卡了我兩個(gè)小時(shí),希望你們能避開我的坑,順利前行
到此這篇關(guān)于C++簡單又輕松的講解類和對象中友元函數(shù)的文章就介紹到這了,更多相關(guān)C++友元函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Visual?Studio2022配置ReSharper?C++?常用設(shè)置方法
這篇文章主要介紹了Visual?Studio2022配置ReSharper?C++?常用設(shè)置,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),文中介紹了卸載Resharper的方法及Resharper激活碼,感興趣的朋友參考下吧2024-01-01C++實(shí)現(xiàn)LeetCode(179.最大組合數(shù))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(179.最大組合數(shù)),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08C++程序的五大內(nèi)存分區(qū)實(shí)例詳解
C++內(nèi)存區(qū)域,一般可分為棧內(nèi)存區(qū)、堆內(nèi)存區(qū)、全局/靜態(tài)內(nèi)存區(qū)、文字常量內(nèi)存區(qū)及程序代碼區(qū)5大分區(qū),本文就帶大家深刻的理解這5大內(nèi)存分區(qū),感興趣的可以了解一下2021-10-10循環(huán)隊(duì)列詳解及隊(duì)列的順序表示和實(shí)現(xiàn)
這篇文章主要介紹了循環(huán)隊(duì)列詳解及隊(duì)列的順序表示和實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-12-12