C++引用

引用
引用是C++新增的復(fù)合類型,引用是以定義變量的別名,用與函數(shù)的形參和返回值
聲明引用的語法
數(shù)據(jù)類型 &引用名 = 原變量名
?
引用的數(shù)據(jù)類型應(yīng)與原變量名的數(shù)據(jù)類型一致
引用名和原變量名可以互換(內(nèi)存地址相同)
必須在聲明時初始化,初始化后不可更改
C語言中&只表示取地址,C++中&還可表示引用
引用的本質(zhì)
引用是指針常量的偽裝
數(shù)據(jù)類型 *const 變量名 = 原變量名指代地址
指向的變量(對象)不可改變,定義的同時必須初始化;可通過解引用的方法修改內(nèi)存中的值
引用本質(zhì)上與指針一樣
程序員擁有引用,但編譯器僅有指針(地址)
?引用的底層邏輯實(shí)際上和指針一樣,不要相信有別名,不要認(rèn)為引用可以節(jié)省一個指針的空間,因為編譯器還會把引用解釋為指針
引用用于函數(shù)的參數(shù)
把函數(shù)的形參聲明為引用,調(diào)用函數(shù)時形參將成為實(shí)參的別名(操作的內(nèi)存區(qū)域一樣)
引用的本質(zhì)是指針,傳遞的是變量的地址,在函數(shù)中修改形參會影響實(shí)參。
?指針常用于函數(shù)的形參和動態(tài)分配
?引用為常量指針,只能用于函數(shù)的形參
使用引用的優(yōu)點(diǎn)
傳引用的代碼更簡潔
傳引用不必使用二級指針
引用的屬性和特別之處
引用的形參與const
const :普通變量、指針、函數(shù)形參加上const修飾表不可改變
這里看一個例子
上面的代碼調(diào)用函數(shù)時,傳入的是變量(有地址),運(yùn)行沒有問題,但是當(dāng)調(diào)用時傳入的是常量(無地址),傳地址和傳引用就會運(yùn)行出錯
?如果引用(指針不可以)的數(shù)據(jù)類型不匹配,當(dāng)引用為const修飾時,C++將創(chuàng)建臨時變量,讓引用指向臨時變量
const int &a = 8;
等價于int temp = 8 ; ?int &a = temp;
?什么時候會創(chuàng)建臨時變量
引用被const修飾時
數(shù)據(jù)類型是正確的,但不是左值
const int &a = 1 ? ?
const int &a = "zhangsan" ??
數(shù)據(jù)類型不正確,但是可以轉(zhuǎn)換為正確的數(shù)據(jù)類型
例如:
字符常量轉(zhuǎn)換為int型('X' ——> 88 )
C風(fēng)格字符串轉(zhuǎn)換為string
結(jié)論
如果函數(shù)的實(shí)參不是左值或與const引用形參的類型不匹配,那么C++將創(chuàng)建正確的數(shù)據(jù)類型的匿名變量,將實(shí)參的值傳給匿名變量,并讓形參來引用該變量
左值:可以被引用的數(shù)據(jù)類型,可以通過地址訪問它們,例如變量、數(shù)組元素、結(jié)構(gòu)體成員、引用和解引用的指針
非左值:包括字面常量(用雙引號包含的字符串除外(字符串常量存在地址))和包含多項的表達(dá)式
將引用形參聲明為const的理由
使用const可以避免無意中修改數(shù)據(jù)的編程錯誤
使用const使函數(shù)能夠處理const和非const實(shí)參,否則將只能接受非const實(shí)參
通過const函數(shù)能正確生成并使用臨時變量
引用用于函數(shù)的返回值
函數(shù)的返回值被拷貝到一個臨時變量(寄存器或棧),然后調(diào)用者程序在使用這個值
double m = sqrt(36);
sqrt()函數(shù)用于返回值的平方根
sqrt(36)的返回值6被拷貝到臨時位置,然后賦值給變量m
cout << sqrt(36)
sqrt(36)的返回值6被拷貝到臨時位置,然后傳遞給cout
??如果返回值為結(jié)構(gòu)體,則將整個結(jié)構(gòu)體拷貝到臨時位置,這會造成性能損耗
解決思路:
??如果返回引用不會拷貝內(nèi)存
語法
返回值的數(shù)據(jù)類型 &函數(shù)名(形參列表){ ? …… ? ?}
注意事項
如果返回值局部變量的引用,其本質(zhì)為野指針
返回函數(shù)的 引用形參、類的成員、全局變量、靜態(tài)變量(static)
返回引用的函數(shù)是被引用變量的別名;如果不希望返回的引用被別人利用,可以將const用于引用的返回類型