C++ 中的引用

Jinku Hu 2023年1月30日 2021年6月28日
  1. 使用 & attr(optional) declarator 表示法在 C++ 中宣告一個 lvalue 引用
  2. 使用引用在 C++ 中實現函式原型
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 <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>

using std::cout; using std::endl;
using std::string; using std::setw;
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 表示法指定,並且物件的訪問方式與左值引用一樣。右值引用用於實現高效的操作,例如移動建構函式和移動賦值以避免大物件的昂貴副本。

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C++ Reference