C++---引用變量(&)

引用變量

引用是已定義變量的別名


創建引用

int a;
int & b  = a; // b爲a的引用
  • 引用(&),b 爲 a 的別名
  • 在函數引用時,必須對其初始化
  • 一個變量可以有多個引用,一個引用只能指向一個實體
  • a 和 b 指向的是同一塊內存空間

將引用作爲參數

引用作爲函數參數,使得函數中的變量名成爲調用函數程序中的變量的別名。這種傳遞稱爲引用傳遞,按引用傳遞允許被調用函數能訪問調用函數中的變量。

void swapr(int & a,int & b); // 引用傳遞
void swapv(int a,int b); // 值傳遞
void swapp(int * a,int * b); // 指針傳遞

swap()爲交換函數,上面三個分別參數爲引用、值、指針。經過我的一番測試發現。函數中的值傳遞並不能改變調用函數中a , b的值。引用和指針則可以。

引用時儘可能使用const

  • 使用const能避免無意中修改數據的編程錯誤
  • 使用const能夠處理const和非const實參,否則只能接受非const數據
  • 使用const引用使函數能正確的生成並使用臨時變量
// 函數聲明
double cube(double &a)
{
    a = a * a;
}
// 調用函數
cube(x+2);

當函數cube()的引用參數應該是可以修改的,但是傳遞的值是(x+2)並不是變量,所以編譯時會出現錯誤。
但是,如果在引用前加上const程序就能運行了,const指定引用不能被修改,所以是否爲變量也就不重要了。但是編譯器會爲其創建一個臨時變量,保存(x+2),然後將 a 成爲臨時變量的引用。

那麼什麼情況下會創建臨時變量呢?如果引用參數是const,則編譯器會在下面兩種情況生成臨時變量:

  • 實參的類型正確,但不爲左值
  • 實參的類型不正確,但可以轉化爲右值

結構的引用

引用非常適合結構和類。引入引用主要是爲了用於這些類型,而非用於基本的內置類型。
引用這麼高效爲什麼內置類型不使用引用呢?
《Effective C++》條款20:寧以pass by reference to const替換pass by value。其中有這麼一句“如果你有個對象屬於內置類型(例如int),pass by value 往往比pass by reference的效率高些”。說白了就是自己的東西用的更順手一些。

使用結構變量引用參數和基本變量一用參數相同,就相當於別名,這裏就不贅述了。

返回一個引用

引用既然能作爲參數,那麼能否作爲返回值呢? 答案是肯定的。

爲什麼要返回引用呢? 毫無疑問,爲了讓程序效率更高。

// 聲明函數:返回值是struct_a 類型的引用
struct_a &  run(struct_a & a,const struct_a & b)
{   
    ...
    return a;
}
// dup接收run的返回值
struct_a dup = run(a,b);

當函數run()返回值爲類型時,dup接收的是一個結構,將把一個結構複製到一個臨時位置,再將這個拷貝複製給dup,消耗空間且效率低。
但返回值爲引用時,直接將a 複製到dup,效率更高

注意:在返回值爲引用時不能返回棧空間的值,函數中創建的臨時變量即使爲引用,但是函數結束後棧空間的內容都會被銷燬,返回將會出現錯誤。

總結

使用引用參數的原因:

  1. 修改調用函數中的函數對象
  2. 通過傳遞引用而不是整個數據對象,提高程序的運行速度

當數據對象較大的時候,第二個原因尤爲重要。這些也是使用指針參數的原因。
那麼指針參數和引用又有什麼區別呢?
引用參數實際上是基於指針的代碼的另一個接口,至此,引用展現了它的廬山真面目,其實它和指針在底層實現沒什麼兩樣,只是在使用上,有時引用會更加順手。

那麼什麼情況下,應該使用何種傳遞參數的方式呢?

  • 數據對象小且不做修改,例如內置類型和小型結構,按值傳遞。
  • 數據對象數組,只能使用指針傳遞。
  • 結構,引用和指針都可以
  • 類,使用引用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章