33

我有一个我很困惑的话题,我需要详细说明。它是 const 版本和非常量版本的运算符重载。

// non-const
double &operator[](int idx) {
    if (idx < length && idx >= 0) {
        return data[idx];
    }
    throw BoundsError();
}

我知道这个 lambda 函数需要一个索引并检查它的有效性,然后返回类中数组数据的索引。还有一个具有相同主体但函数调用为的函数

const double &operator[](int idx) const

为什么我们需要两个版本?

例如,在下面的示例代码中,下面的每个实例使用的是哪个版本?

Array a(3);
a[0] = 2.0;
a[1] = 3.3;
a[2] = a[0] + a[1];

我的假设是 const 版本仅被调用是a[2]因为我们不想冒险修改a[0]or a[1]

谢谢你的帮助。

4

2 回答 2

35

当两个版本都可用时,逻辑非常简单:constconst对象调用const版本,为非对象调用非版本const。就这样。

在您的代码示例a中是一个非const对象,这意味着const在所有情况下都会调用非版本。您的示例中永远不会调用该const版本。

拥有两个版本的目的是实现对非const对象的“读/写”访问和对对象的仅“读”访问const。对于const对象const的版本operator []被调用,它返回一个const double &引用。您可以通过该 const 引用读取数据,但不能通过它进行写入。

于 2013-10-08T01:11:09.457 回答
3

提供一个代码示例来补充上面的答案:

Array a(3);
a[0] = 2.0;  //non-const version called on non-const 'a' object

const Array b(3);
double var = b[1];  //const version called on const 'b' object

const Array c(3);
c[0] = 2.0;  //compile error, cannot modify const object
于 2018-10-16T00:50:29.023 回答