背景
實際項目中涉及到對 C++ 引用的使用,這里記錄個人對其的理解嘴纺,并把它加入到個人「專業(yè)」知識結(jié)構(gòu)
是什么
- 在 C++ 編程語言中的引用是一種「復合數(shù)據(jù)類型」,是在基本類型的基礎上衍生出來的類型
- 從 C 語言中的「指針」衍生出來的比指針「安全」但沒有指針強大的一種數(shù)據(jù)類型
- 在實現(xiàn)上,引用可以作為「已存在」的「對象」的「新名字」哈踱。舉個例子送悔,如圖所示慢显,假設 obj 變量在內(nèi)存中 0x08E4100 地址處,我們定義一個 reference 引用 obj 對象欠啤,則 reference 變量的地址也是 0x08E4100
為什么
從使用的角度來分析荚藻,C++ 語言使用引用是為了解決函數(shù)調(diào)用時參數(shù)拷貝導致的性能問題
怎么用
方法參數(shù)
引用作為方法參數(shù)可以實現(xiàn)傳出「方法結(jié)果」的目的
void square(int x, int& result)
{
result = x * x;
}
- 上面 square 方法調(diào)用后,從 result 變量可以拿到 x 的平方信息
- 調(diào)用方不用進行不必要的取地址操作洁段,更「節(jié)省時間」
方法返回值
int& preinc(int& x)
{
return ++x; // "return x++;" 這樣寫會出錯应狱?臨時對象?
}
preinc(y) = 5; // 等同于 ++y, y = 5;
- 方法返回引用可以作為「左值」被賦值
- 不要返回「局部」對象的引用祠丝,因為調(diào)用結(jié)束后棧上局部對象的「內(nèi)存」會被后續(xù)函數(shù)調(diào)用破壞
- 因為引用就是「原對象」的「別名」疾呻,故把它當做原對象使用,左值和右值都一樣使用
優(yōu)化方法調(diào)用時參數(shù)拷貝開銷
void f_slow(BigObject x) { /* ... */ }
void f_fast(const BigObject& x) { /* ... */ }
BigObject y;
f_slow(y); // 很慢写半,因為要拷貝 y 對象到 x 對象
f_fast(y); // 很快岸蜗,因為直接訪問只讀變量 y 的地址
- 通常函數(shù)調(diào)用時使用 const T & 可以減少「對象拷貝」時間開銷
- 如果 f_fast 內(nèi)部需要對 y 「對象的副本」進行操作,那么需要自己拷貝一份
- 雖然傳遞「大對象」可以用指針解決污朽,但是「小對象」就沒必要了散吵,然而引用更靈活,不管大小對象都適用蟆肆,兼容性好
內(nèi)部原理
- 編譯器是如何處理引用的矾睦?
優(yōu)缺點
- 優(yōu)點是減少函數(shù)調(diào)用時參數(shù)拷貝的性能開銷
最佳實踐
- 不要返回函數(shù)局部對象的引用,棧上數(shù)據(jù)會被后續(xù)函數(shù)修改
- 函數(shù)參數(shù)盡量使用引用
練習題
- 對比引用和被引用對象的地址炎功,在使用層面理解引用的本質(zhì)
總結(jié)
- 最后得出一句話「引用就是變量的別名枚冗,指向同一個內(nèi)存地址」