網站首頁 編程語言 正文
友元
用到關鍵字 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卡了我兩個小時,希望你們能避開我的坑,順利前行
原文鏈接:https://ylqb196.blog.csdn.net/article/details/125093851
相關推薦
- 2022-02-02 es 同步索引報錯:ElasticSearch ClusterBlockException[bloc
- 2022-07-19 Linux應該怎么使用命令
- 2023-06-21 python相對包導入報“Attempted?relative?import?in?non-pack
- 2021-12-10 linux防火墻配置(基于yum倉的配置)詳細步驟_Linux
- 2022-08-02 Python深拷貝淺拷貝圖文示例清晰整理_python
- 2022-06-06 webpack4.0-解決webpack 報The 'mode' option has not be
- 2023-01-11 基于Qt播放器的實現詳解(支持Rgb,YUV格式)_C 語言
- 2022-05-31 如何利用python給微信公眾號發消息實例代碼_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支