7. 索引运算符重载

重载索引运算符([]) 可以将一个对象作为一维数组来使用。

如,我们可以像如下代码一样使用。

MyClass m;

int x = c[100];  //  需要重载 [] 运算符。

示例

以下定义一个动态生成整数等差数列的容器类 MyRange,该类给出在创建时给出开始的整数值(start)、结束的整数值(stop,不包含 stop)和步长(step,默认为1)。其内部动态生成相应的整数。如:

MyRange r1(3, 6);  // 生成 3、4、5
MyRange r2(1, 10, 3);  // 生成 1、4、7
MyRange r3(10, 0, -2);  // 生成 10、8、6、4、2

接下来我们使用索引运算符就可以获取其中的数据,如

cout << r2[0] << endl; // 打印 1
cout << r2[1] << endl; // 打印 4
cout << r2[100] << endl; // 打印 0, 索引越界返回 0

完整示例代码

// filename: op_index.cpp
#include <iostream>

using namespace std;

class MyRange{
    public:
        MyRange(int begin, int end, int stp=1): start(begin), stop(end), step(stp) {}
        // 重载 [] 运算符
        int operator [] (int index) {
            int value = start + index * step;
            if (step > 0 && value > stop) 
                return 0; // 越界
            else if (step < 0 && value < stop) 
                return 0; // 越界

            return value;
        }
    private:
        int start;
        int stop;
        int step;
    friend ostream & operator << (ostream & o, const MyRange &c);
};

ostream & operator << (ostream & o, const MyRange &c) {
    o << "[";
    if (c.step > 0)
        for (int v = c.start; v < c.stop; v += c.step) {
            if (v != c.start)
                o << ",";
            o << v;
        }
    else
        for (int v = c.start; v > c.stop; v += c.step) {
            if (v != c.start)
                o << ", ";
            o << v;
        }
    o << "]";
    return o;
}

int main(int argc, char * argv[]) {
    MyRange r1(3, 6);  // 生成 3、4、5
    MyRange r2(1, 10, 3);  // 生成 1、4、7
    MyRange r3(10, 0, -2);  // 生成 10、8、6、4、2

    cout << r1 << endl;
    cout << r2 << endl;
    cout << r3 << endl;

    cout << r2[0] << endl; // 打印 1
    cout << r2[1] << endl; // 打印 4
    cout << r2[100] << endl; // 打印 0, 索引越界返回 0

    return 0;
}

编译和运行结果如下

weimz@mzstudio:~$ g++ -o op_index op_index.cpp
weimz@mzstudio:~$ ./op_index 
[3,4,5]
[1,4,7]
[10, 8, 6, 4, 2]
1
4
0