網(wǎng)站首頁(yè) 編程語言 正文
1.引用的概念
引用不是新定義一個(gè)變量,而是給已存在變量取了一個(gè)別名,編譯器不會(huì)為引用變量開辟內(nèi)存空間,它和它引用的變量共用同一塊內(nèi)存空間。
2.引用的格式
類型 & 引用變量名 ( 對(duì)象名 ) = 引用實(shí)體;
舉例如下:
注意:引用類型必須和引用實(shí)體是同種類型的
3.引用的特性
(1). 引用在 定義時(shí)必須初始化
例如:int& d; 這樣就是沒有初始化是錯(cuò)的
(2). 一個(gè)變量可以有多個(gè)引用
?? ?int a = 10;
?? ?int& b = a;
?? ?int& c = b;
?? ?int* p = &b; ? ?//p是指針
(3). 引用一旦引用一個(gè)實(shí)體,再不能引用其他實(shí)體
4.取別名原則
對(duì)原引用變量,權(quán)限只能縮小,即 可讀可寫(普通類型) 可以改成 只讀(const);不能放大:,即 只讀 不能改成 可讀可寫的
例子1:權(quán)限的放大,不能把const給非const
例子2:權(quán)限的縮小 非const 既可以給非const,也可以給const:
例子3:權(quán)限縮小和放大規(guī)則:適用于引用和指針間
例子4: 權(quán)限不適用于普通賦值:
難點(diǎn):隱式類型轉(zhuǎn)換的引用
整形e能否做雙精度浮點(diǎn)型d的別名呢?
直接賦值是不行的,需要加上const才正確。即:const int& e = d;
正確
解釋:隱式類型轉(zhuǎn)換的普通賦值的情況,上面的例子:int f=d;從語法上看把8字節(jié)的d不能直接給4字節(jié)的f,因?yàn)楦↑c(diǎn)數(shù)和整形的存儲(chǔ)形式就不一樣,沒辦法直接截取,所以d需要先把整數(shù)部分給一個(gè)4字節(jié)的臨時(shí)變量,再把臨時(shí)變量給f
再看引用:int& e=d;
臨時(shí)變量具有常性,所以這里把臨時(shí)變量給引用e的時(shí)候,相當(dāng)于是把自帶const的臨時(shí)變量賦值給非const的e,把只讀的給可讀可寫的是放大了權(quán)限,所以錯(cuò)誤;必須改成const int& e=d;
才正確!
5.引用的使用場(chǎng)景
做參數(shù)
(1)傳參:實(shí)參給形參傳值和傳地址都需要傳一份值/地址的拷貝,引用傳參可以減少拷貝,提高效率
void Swap(int& x, int& y) { int tmp = x; x = y; y = tmp; } void Swap(double& x, double& y) { double tmp = x; x = y; y = tmp; } int main() { int a = 0, b = 1; swap(a, b); double c = 1.1, d = 2.2; swap(c, d); return 0; }
(2)作輸出型參數(shù):
leetcode上的題往往有輸出型參數(shù),在c++中就可以用引用代替更加方便
做返回值
int&Count()的講解
傳值返回:會(huì)有一個(gè)拷貝
傳引用返回:沒有這個(gè)拷貝了,函數(shù)返回的直接就是返回變量的別名
int& Count() { int n = 0; n++; return n; } int main() { int ret = Count(); return 0; }
首先我們來看普通的傳值返回:普通的傳值返回需要把返回值n給一個(gè)函數(shù)類型int的臨時(shí)變量(函數(shù)類型就是返回值類型),再把臨時(shí)變量給ret。
為什么設(shè)計(jì)一個(gè)臨時(shí)變量,直接把n給ret不行嗎?
答:不行,因?yàn)楫?dāng)函數(shù)Count里執(zhí)行完各種代碼后,返回n,等出了Count函數(shù)的作用域后n就會(huì)銷毀,所以不能直接把n給ret,需要一個(gè)臨時(shí)變量。
如何證明返回時(shí)存在臨時(shí)變量呢?:如果你用int& ret 接收,寫成int& ret = Count();
發(fā)現(xiàn)無法運(yùn)行,因?yàn)榕R時(shí)變量有常性,所以需要寫成const int& ret = Count();
才能通過。
此時(shí)再看傳引用返回:
當(dāng)用引用接收引用返回時(shí):這里ret和n的地址一樣,也就意味著ret其實(shí)就是n的別名。但是因?yàn)閚出作用域不會(huì)立即被覆蓋,所以第一次通過ret可以打印是1,當(dāng)打印第二次時(shí),因?yàn)榍懊嬉呀?jīng)調(diào)用過一次打印函數(shù),已 "銷毀" 的Count函數(shù)棧幀在此時(shí)被打印函數(shù)覆蓋,再打印ret就會(huì)是隨機(jī)數(shù)了!
即:如果函數(shù)返回時(shí),出了函數(shù)作用域,如果返回對(duì)象還未還給系統(tǒng),則可以使用引用返回,如果已 經(jīng)還給系統(tǒng)了,則必須使用傳值返回。
用static修飾n后:用static靜態(tài)變量使n只初始化一次且改變其生命周期,把n放進(jìn)了靜態(tài)區(qū),這樣n就一直存在,就可以通過ret找到n了,再怎么打印ret都是1.
傳值傳引用效率比較
以值作為參數(shù)或者返回值類型,在傳參和返回期間,函數(shù)不會(huì)直接傳遞實(shí)參或者將變量本身直接返回,而是傳遞實(shí)參或者返回變量的一份臨時(shí)的拷貝,因此用值作為參數(shù)或者返回值類型,效率是非常低下的,尤其是 當(dāng)參數(shù)或者返回值類型非常大時(shí),效率就更低。 總結(jié):傳值和指針在作為傳參以及返回值類型上效率相差很大 。
6.引用和指針的不同點(diǎn)
1. 引用 在定義時(shí) 必須初始化 ,指針沒有要求
2. 引用 在初始化時(shí)引用一個(gè)實(shí)體后,就 不能再引用其他實(shí)體 ,而指針可以在任何時(shí)候指向任何一個(gè)同類型 實(shí)體
3. 沒有 NULL 引用 ,但有 NULL 指針
4. 在 sizeof 中含義不同 : 引用 結(jié)果為 引用類型的大小 ,但 指針 始終是 地址空間所占字節(jié)個(gè)數(shù) (32 位平臺(tái)下占 4 個(gè)字節(jié) )
5. 引用自加即引用的實(shí)體增加 1 ,指針自加即指針向后偏移一個(gè)類型的大小
6. 有多級(jí)指針,但是沒有多級(jí)引用
7. 訪問實(shí)體方式不同, 指針需要顯式解引用,引用編譯器自己處理
8. 引用比指針使用起來相對(duì)更安全
引用和指針在語法上是不一樣的,但是實(shí)際上從反匯編的代碼上我們能看到引用和指針的底層實(shí)現(xiàn)是一樣的!
這就好比保時(shí)捷的卡宴和大眾的途銳汽車,他們的三大件底盤,發(fā)動(dòng)機(jī),變速箱都是一樣的,但是他們的品牌不一樣,價(jià)格不同
原文鏈接:https://blog.csdn.net/zhang_si_hang/article/details/124689560
相關(guān)推薦
- 2023-03-22 tkinter如何實(shí)現(xiàn)打開文件對(duì)話框并獲取文件絕對(duì)路徑_python
- 2022-08-30 Linux常用tar命令
- 2021-12-01 docker網(wǎng)絡(luò)配置過程詳解介紹_Android
- 2023-05-30 Pandas.DataFrame行和列的轉(zhuǎn)置的實(shí)現(xiàn)_python
- 2024-03-05 git的使用
- 2022-09-25 ORACLE數(shù)據(jù)庫(kù)數(shù)據(jù)泵的導(dǎo)入導(dǎo)出
- 2023-02-06 Python類中__init__()?和self的詳細(xì)解析_python
- 2022-10-02 React函數(shù)組件和類組件的區(qū)別及說明_React
- 最近更新
-
- 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)證過濾器
- Spring Security概述快速入門
- 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)程分支