C++ 左值引用與一級指針

左值引用用於一級指針時,有以下幾種用法:

//方式一:引用一級指針,常規用法
int a = 5;
int * pa = &a;
int * &rpa = pa;

//方式二:引用指向常量的一級指針,以下幾種為等效表示
int a = 5;
const int * pa = &a;
const int * &rpac = pa; //方式一
int const * &rpac = pa; //方式二

//方式三:引用一級指針的常引用,引用自身為常量
int a = 5;
int * pa = &a;
int * const &crpa = pa;

//方式四:引用指向常量的一級指針,且引用自身為常量,以下幾種為等效表示
int a = 5;
int * pa = &a;
const int * const &crpac = pa; //方式一
int const * const &crpac = pa; //方式二

Microsoft Visual Studio 中連續多個 const 會被編譯器解釋成一個,即 const const const const int *&const int *& 等效,除此之外,const int const *&Microsoft Visual Studio 中也與 const int *& 等效,而 int *& constQT minGW 中將會報錯,在 Microsoft Visual Studio 中與 int *& 等效。

各類型引用可修改屬性如下表所示:

引用類型 修改 *rp 修改 rp
int * &rp 可以 可以
const int * &rp 不可以 可以
int * const &rp 可以 不可以
const int * const &rp 不可以 不可以

若將變數的地址賦予引用(例如 rp=&x),各類型引用可接受的變數地址如下表所示:

引用類型 int變數地址 const int變數地址
int * &rp 不可以 不可以
const int * &rp 不可以 不可以
int * const &rp 聲明時可以(將創建臨時變數) 不可以
const int * const &rp 聲明時可以(將創建臨時變數) 聲明時可以(將創建臨時變數)

若將一級指針變數賦予引用(例如 rp=p),各類型引用可接受的一級指針變數如下表所示。若賦值時等號右邊是函數返回的臨時指針變數(屬於右值),則只有當等號左邊為 int * const & 以及 const int * const & 類型時不會報錯,此時必會創建臨時變數(與 const 左值引用性質一致)。

引用類型 int *變數 const int *變數 int * const變數 const int * const變數
int * &rp 可以 不可以 不可以 不可以
const int * &rp 不可以 可以 不可以 不可以
int * const &rp 聲明時可以 不可以 聲明時可以 不可以
const int * const &rp 聲明時可以(將創建臨時變數) 聲明時可以 聲明時可以(將創建臨時變數) 聲明時可以

若將引用變數賦予引用(例如 rp=rp2),各類型引用可接受的引用變數如下表所示。比較上下兩表可知,左值引用類型變數被初始化完畢後,若要將其賦值給另一引用變數,賦值時的表現與所引用類型的變數相一致。

引用類型 int *&變數 const int *&變數 int * const&變數 const int * const&變數
int * &rp 可以 不可以 不可以 不可以
const int * &rp 不可以 可以 不可以 不可以
int * const &rp 聲明時可以 不可以 聲明時可以 不可以
const int * const &rp 聲明時可以(將創建臨時變數) 聲明時可以 聲明時可以(將創建臨時變數) 聲明時可以