C++ - 重载 [] 运算符

25

我有一个模板类Array:

template <class T=int, int SIZE=10>
class Array {
    T TheArray[SIZE];
public:
    void Initialize() {
        for (int idx=0; idx < SIZE; idx++) {
            TheArray[idx] = T();
        }
    }

    T& operator [](int idx) {
        return TheArray[idx];
    }

    T operator [](int idx) const {
        return TheArray[idx];
    }
}

我对运算符[]重载有一些问题(我在网上找到了这个例子)。

我理解T& operator [](int idx)返回索引为idx的数组值的引用,而T operator [](int idx) const返回它的值。 然而,我不确定在什么情况下使用[]运算符会返回引用或值。

此外,如果我将T operator [](int idx) const更改为T operator [](int idx),编译器会报错。为什么呢? 我可以理解编译器之所以会报错是因为只有返回类型不同,但为什么添加const时它不会报错呢?这只意味着类内部没有被修改,对吗?

我尝试调试这个小的主要实现:

int main() {
    int val;
    Array<> intArray;

    intArray.Initialize();
    val = intArray[1];
    printf("%d", intArray[1]);
    intArray[1] = 5;
}

每次调用T& operator [](int idx),为什么会这样?谢谢。

顺便提一下,最好使用适当的构造函数来代替像 initialize 这样的函数。C++ 为对象初始化提供了一个完美的工具,那就是构造函数。 - SergeyA
2个回答

24
operator[] 重载将基于您调用它的对象的 const 限定符进行选择。
Array<> intArray;
intArray[1]; //calls T& operator[]

const Array<> constArray;
constArray[1]; //calls T operator[]

如果你从 T operator[] 中去掉 const,那么会出现错误,因为成员函数不能具有相同的 const 限定符和参数,否则就无法在它们之间进行选择。

14

首先,将[]视为调用this->operator[]的语法糖。

如果this是一个const指针,则将调用const版本,否则将调用非const版本。

接下来,您应该使用const T& operator [](int idx) const {,即使const版本返回const引用。这将节省进行深度复制的开销。

最后,函数的const性质确实是其签名的一部分。这使得您可以根据const性质进行重载。否则,您就无法拥有两个operator[]版本。


1
在这里,我甚至会称返回临时引用而不是const引用为设计上的问题/错误,因为它会导致不一致性,例如:为什么我不能在memcpy中使用const参数? 人们应该以标准库为导向,以避免出现意外行为,std::vector返回一个const引用。 - AliciaBytes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接