網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
為什么使用成員函數(shù)和友元函數(shù)
這個(gè)問(wèn)題至關(guān)重要,直接影響著后面的理解:
程序數(shù)據(jù): 數(shù)據(jù)是程序的信息,會(huì)受到程序函數(shù)的影響。封裝是面向?qū)ο缶幊讨械陌褦?shù)據(jù)和操作數(shù)據(jù)的函數(shù)綁定在一起的一個(gè)概念,這樣能避免受到外界的干擾和誤用,從而確保了安全。
數(shù)據(jù)封裝引申出了另一個(gè)重要的 OOP 概念,即 數(shù)據(jù)隱藏 。數(shù)據(jù)封裝 是一種把數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)捆綁在一起的機(jī)制, 數(shù)據(jù)抽象 是一種僅向用戶暴露接口而把具體的實(shí)現(xiàn)細(xì)節(jié)隱藏起來(lái)的機(jī)制。C++ 通過(guò)創(chuàng)建類來(lái)支持封裝和數(shù)據(jù)隱藏(public、protected、private)。我們已經(jīng)知道,類包含私有成員(private)、保護(hù)成員(protected)和公有成員(public)成員。默認(rèn)情況下,在類中定義的所有項(xiàng)目都是私有的。
由于C++的封裝和隱藏特性,只有類定義的成員函數(shù)可以訪問(wèn)類定義的私有數(shù)據(jù)。
成員函數(shù)是數(shù)據(jù)封裝和數(shù)據(jù)隱藏的機(jī)制。
友元是C++提供的一種破壞數(shù)據(jù)封裝和數(shù)據(jù)隱藏的機(jī)制。
成員函數(shù)的使用
首先先看代碼
class Stock{ //class declaration private: std:: string company; long shares; double share_val; double total_val; void set_tot(){ total_val=shares* share_val;} public: void acquire(const std:: string & co, long n, double pr); void buy(long num, double price); void se11(long num, double price); void update(double price); void show(); };//note semicolon at the end
注意這里面的private可以不寫(xiě),如果不寫(xiě)的話默認(rèn)是私有的。
其中,company、shares等都是Stock類的私有數(shù)據(jù)成員。如果試圖使用非成員函數(shù)訪問(wèn)這些數(shù)據(jù)成員編譯器禁止這樣做。如果試圖破解該機(jī)制,友元是另一種選擇。
實(shí)現(xiàn)類成員函數(shù)
(1)定義成員函數(shù)時(shí),使用作用域解析運(yùn)算符(::)來(lái)標(biāo)識(shí)函數(shù)所屬的類;
void Stock::update(double price)
(2)類方法可以訪問(wèn)類的private組件。
友元
C++是從結(jié)構(gòu)化的C語(yǔ)言發(fā)展而來(lái)的,需要照顧結(jié)構(gòu)化設(shè)計(jì)程序員的習(xí)慣,所以在對(duì)私有成員可訪問(wèn)范圍的問(wèn)題上不可限制太死。
C++設(shè)計(jì)者認(rèn)為,如果有的程序員真的非常怕麻煩,就是想在類的成員函數(shù)外部直接訪問(wèn)對(duì)象的私有成員,那還是做一點(diǎn)妥協(xié)以滿足他們的愿望為好,這也算是眼前利益和長(zhǎng)遠(yuǎn)利益的折中。因此,C++就有了友元(friend)的概念。打個(gè)比方,這相當(dāng)于是說(shuō):朋友是值得信任的,所以可以對(duì)他們公開(kāi)一些自己的隱私。
友元提供了一種普通函數(shù)或者類成員函數(shù)訪問(wèn)另一個(gè)類中的私有或保護(hù)成員的機(jī)制。也就是說(shuō)有兩種形式的友元:
(1)友元函數(shù):普通函數(shù)對(duì)一個(gè)訪問(wèn)某個(gè)類中的私有或保護(hù)成員。
(2)友元類:類A中的成員函數(shù)訪問(wèn)類B中的私有或保護(hù)成員。
(3)友元成員函數(shù)
友元函數(shù)
創(chuàng)建友元函數(shù)的第一步是將其原型放在類聲明中,并在原型聲明前加上關(guān)鍵字friend:
friend Time operator*(double m,constTime&t);
注意該聲明可以在類外也可以在類中
這樣即使operator不是成員函數(shù) ,但它與成員函數(shù)的訪問(wèn)權(quán)限相同,可以訪問(wèn)類中的私有變量。
友元類
類Y的所有成員函數(shù)都為類X友元函數(shù)
class girl; class girl{ private: char *name; int age; friend boy; //聲明類boy是類girl的友元 }; class boy{ public: void disp(girl &); }; void boy::disp(girl &x) //函數(shù)disp()為類boy的成員函數(shù),也是類girl的友元函數(shù) { //借助友元,在boy的成員函數(shù)disp中,借助girl的對(duì)象,直接訪問(wèn)girl的私有變量 cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl; }
成員函數(shù)作友元
類Y的一個(gè)成員函數(shù)為類X的友元函數(shù)
目的:使類Y的一個(gè)成員函數(shù)成為類X的友元,具體而言:在類Y的這個(gè)成員函數(shù)中,借助參數(shù)X,可以直接使用X的私有變量
語(yǔ)法:聲明在公有中 (本身為函數(shù))
聲明:friend + 成員函數(shù)的聲明
調(diào)用:先定義Y的對(duì)象y—使用y調(diào)用自己的成員函數(shù)—自己的成員函數(shù)中使用了友元機(jī)制
class Stock{ //class declaration private: std:: string company; long shares; double share_val; double total_val; void set_tot(){ total_val=shares* share_val;} public: void acquire(const std:: string & co, long n, double pr); void buy(long num, double price); void se11(long num, double price); void update(double price); void show(); }; class Market{ friend void Stock::acquire(const std:: string & co, long n, double pr); //Stock類下的acquire可以作為該成員函數(shù)的友元函數(shù),可以訪問(wèn)該類的私有變量 int price; int fiture; public: void stuff(); };
如代碼所示,Stock類下的acquire函數(shù)作為Market的友元函數(shù)可以訪問(wèn)market類的私有變量。
友元函數(shù)和類的成員函數(shù)的區(qū)別
友元函數(shù)和類的成員函數(shù)的區(qū)別成員函數(shù)有this指針,而友元函數(shù)沒(méi)有this指針。友元函數(shù)是不能被繼承的,就像父親的朋友未必是兒子的朋友。
總結(jié)
原文鏈接:https://blog.csdn.net/weixin_44282063/article/details/122693219
相關(guān)推薦
- 2022-10-17 Qt中TCP協(xié)議通信詳解_C 語(yǔ)言
- 2023-12-15 log4j.properties自定義日志配置
- 2022-06-09 Python字符串的轉(zhuǎn)義字符_python
- 2023-05-30 基于CUDA?out?of?memory的一種神奇解決方式_python
- 2022-05-23 C語(yǔ)言也有封裝,繼承和多態(tài)你知道嗎_C 語(yǔ)言
- 2023-03-13 pandas行和列的獲取的實(shí)現(xiàn)_python
- 2022-08-23 python?matplotlib畫(huà)圖時(shí)坐標(biāo)軸重疊顯示不全和圖片保存時(shí)不完整的問(wèn)題解決_python
- 2023-07-05 Redis性能瓶頸:如何優(yōu)化大key問(wèn)題?
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支