Skip to main content

11-4 重載 [] 運算子

現在我們還缺一個重要的功能,那就是存取 Vec 裡的值。

試著執行這段程式看看。

[main.cpp]

#include <iostream>
#include "vec.h"

using namespace std;

int main()
{
    Vec a;

    a.push_back(1);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(3);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(5);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(7);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(9);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;

    for(int i=0; i<a.size(); i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    return 0;
}

我們會得到這個錯誤訊息。

error: no match for 'operator[]' (operand types are 'Vec' and 'int')|

因為在第 23 行中的cout << a[i],編譯器不知道 Vec [] 要怎麼處理。

[]是一個運算子,每種資料型別的 [] 運算可能有所不同,我們必須自己實作 Vec 的 [] 運算子運算。

在 Vec 宣告的尾端加入這行重載 [] 運算子的成員函數。

    ...
    void pop_back();
    int& operator[] (int index); // <== 加入這行
};

在函數實作部分加入。

int& Vec::operator[] (int index)
{
    return m_data[index];
}

這段程式碼是在做什麼呢? 我們把它拆解成四個部分來看。

  • int&(回傳型態):注意那個 & 符號,它代表「參照」(Reference)。意思是它不只傳回那個數字的值,而是直接把那塊記憶體的「真身」給你。這樣你才能寫出像 a[0] = 10; 這樣的程式碼,直接修改裡面的數值。

  • Vec::(所屬類別):這代表這個功能是屬於 Vec 這個類別。

  • operator[](函數名稱):這是 C++ 的特殊關鍵字。組合起來就是告訴編譯器:「我要重新定義中括號 [] 的功能」。

  • (int index)(參數):中括號裡面填的數字(索引值)。例如 a[3],這個 index 就是 3。

現在可以執行這段程式來驗證了。

[main.cpp]

#include <iostream>
#include "vec.h"

using namespace std;

int main()
{
    Vec a;

    a.push_back(1);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(3);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(5);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(7);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;
    a.push_back(9);
    cout << "Cap:" << a.capacity() << " Size:" << a.size() << endl;

    for(int i=0; i<a.size(); i++)
    {
        cout << a[i] << " ";  // 1 3 5 7 9
        a[i] = a[i]*2; // 把值修改為 2 倍
    }
    cout << endl;

    for(int i=0; i<a.size(); i++)
    {
        cout << a[i] << " ";  // 2 6 10 14 18
    }
    cout << endl;

    return 0;
}
Cap:1 Size:1 Cap:2 Size:2 Cap:4 Size:3 Cap:4 Size:4 Cap:8 Size:5 1 3 5 7 9 2 6 10 14 18