C++ 常量和非常量运算符重载

C++ 常量和非常量运算符重载,c++,operator-overloading,constants,C++,Operator Overloading,Constants,我有一个我很困惑的话题,我需要详细说明一下。它是常量版本和非常量版本的运算符重载 // non-const double &operator[](int idx) { if (idx < length && idx >= 0) { return data[idx]; } throw BoundsError(); } 为什么我们需要两个版本 例如,在下面的示例代码中,下面的每个实例使用哪个版本 Array a(3); a

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

// non-const
double &operator[](int idx) {
    if (idx < length && idx >= 0) {
        return data[idx];
    }
    throw BoundsError();
}
为什么我们需要两个版本

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

Array a(3);
a[0] = 2.0;
a[1] = 3.3;
a[2] = a[0] + a[1];
我的假设是,const版本只在
a[2]
上调用,因为我们不想冒险修改
a[0]
a[1]


感谢您的帮助。

当两个版本都可用时,逻辑非常简单:
const
版本用于
const
对象,非
const
版本用于非
const
对象。就这些

在代码示例中,
a
是一个非
const
对象,这意味着在所有情况下都会调用非
const
版本。示例中从未调用
const
版本


有两个版本的要点是对非
const
对象实现“读/写”访问,而对
const
对象仅实现“读”访问。对于
const
对象,调用
const
版本的
运算符[]
,它返回一个
constdouble&
引用。您可以通过该常量引用读取数据,但不能通过它写入数据。

要提供代码示例以补充上述答案,请执行以下操作:

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

你可以很容易地检查哪一个被调用,里面有输出。这是在一张讲课幻灯片中,所以我希望我不必创建一个类来利用它们,只要有人帮助我理解为什么我们要这样做不要懒惰,自己试试看,你会记得更清楚。我的假设是const版本只在
a[2]上调用
因为我们不想冒险修改
a[0]
a[1]
。这毫无意义,操作
a[2]
不涉及
a[0]
a[1]
,它涉及
a
和整数文本
2
。我发现这段视频很有帮助:。直接跳到8:15我不知道——我发现很难调用非常量版本。请观看此实况演示:@Reb.Cabin:在您的演示中,您从未尝试呼叫非常量版本的
操作员[]
。每次你有这样的机会,你都会使用
this->elems[i]
。请注意,
this->elems
是一个普通的原始指针。它的操作符
[]
是普通的内置索引器,而不是重载索引器。如果要调用重载的非常量版本的
运算符[]
,必须在赋值的左侧使用
(*this)[i]
,而不是
this->elems[i]
。我明白了。我重新编写了ctor,这是一个使用非常量索引器的更好示例。有用的、澄清的评论@AnT在关系运算符重载的情况下,我们应该提供两者还是只提供一个就足够了?在这种情况下,我们应该使用哪一种。例如,
bool运算符
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