C++ 中的引用
本文演示瞭如何在 C++ 中使用引用的多種方法。
使用 & attr(optional) declarator
表示法在 C++ 中宣告一個 lvalue
引用
引用定義物件的替代名稱。它們本身不是物件,因此,我們不能擁有引用陣列或指向引用的指標。引用只引用已經存在的物件,並且它們繫結到這些物件,這意味著宣告後不允許修改。
另外,引用必須被初始化,當使用引用名稱進行操作時,繫結物件被修改。請注意,後一個特性使它們與指標非常相似。我們可以將引用視為指標的替代品,除了前者可以用作常規變數名稱而無需取消引用符號來訪問相應物件的值。如果我們想模仿引用的行為,我們可以宣告一個指向給定型別的 const
指標。除了訪問值的符號外,後者具有與引用相同的特徵。
在下面的示例程式碼中,變數 xr
被宣告為對 x
的引用,代表一個 int
物件。一旦 xr
在宣告期間被初始化,它就不能被重新分配以引用任何型別的不同物件。另一方面,我們可以為它引用的同一物件定義不同的別名,例如 xr
。即,xrc
是一個 const
限定引用,這意味著只能訪問相應物件的值,不能使用別名進行修改。
#include <iostream>
using std::cout;
using std::endl;
int main() {
int x = 5;
int& xr = x;
const int& xrc = x;
xr *= xr;
// xrc *= x; Error
cout << "xr: " << xr << endl;
cout << "xrc: " << xrc << endl;
return EXIT_SUCCESS;
}
輸出:
xr: 25
xrc: 25
我們可以宣告對同一個物件的多個引用,如下面的程式碼片段所示。儘管如此,人們應該意識到任何別名的修改都會影響同一個物件。
#include <iostream>
using std::cout;
using std::endl;
int main() {
int x = 5;
int& xr = x;
int& xrr = x;
xr *= xr;
xrr *= xrr;
cout << "xr: " << xr << endl;
cout << "xrr: " << xrr << endl;
return EXIT_SUCCESS;
}
輸出:
xr: 625
xrr: 625
使用引用在 C++ 中實現函式原型
引用主要用於提供更清晰的函式介面,但也因為 C++ 語言提供了運算子過載功能,並且所有運算子的符號都應該相同。如果語言中沒有引用概念,後者會很複雜。因此,使用需要將引數作為指標的運算子可能看起來像++&x
。
需要使用物件來訪問值的函式可以將相應的引數指定為 const
引用,如果不需要 const
也需要修改。例如,printVector
函式採用 const
引用 std::vector
將元素列印到 cout
流,但 swapElements
需要交換每個元素,因此我們需要定期引用物體。
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using std::cout;
using std::endl;
using std::setw;
using std::string;
using std::vector;
template <typename T>
void printVector(const vector<T> &vec) {
for (auto &i : vec) {
cout << i << "; ";
}
cout << endl;
}
template <typename T>
void swapElements(vector<T> &vec) {
for (auto iter = vec.begin(); iter < vec.end() - 1; ++iter) {
std::swap(*iter, *(iter + 1));
}
}
int main() {
vector<int> vec1 = {43, 5, 123, 94, 359, -23, 2, -1};
printVector(vec1);
swapElements(vec1);
printVector(vec1);
return EXIT_SUCCESS;
}
輸出:
43; 5; 123; 94; 359; -23; 2; -1;
5; 123; 94; 359; -23; 2; -1; 43
請注意,所有先前的引用示例,包括 const
引用,都稱為左值引用。這些引用用於引用我們訪問或修改它們後需要保留有效值的物件。C++ 語言還提供了右值引用,用於引用臨時物件。
臨時物件是程式設計師的一個假設,即不會再次使用給定的物件。右值引用使用 && attr(optional) declarator
表示法指定,並且物件的訪問方式與左值引用一樣。右值引用用於實現高效的操作,例如移動建構函式和移動賦值以避免大物件的昂貴副本。